ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 멀티 테넌시 아키텍처 완벽 가이드: SaaS 서비스의 핵심 설계 패턴
    아키텍처 설계/시스템 아키텍처 2026. 1. 4. 22:34
    반응형

    SaaS 서비스를 설계하다 보면 반드시 마주치는 개념이 있습니다. 바로 멀티 테넌시(Multi-Tenancy)입니다.

    이 글에서는 멀티 테넌시가 무엇인지, 어떤 구현 방식이 있는지, 그리고 실무에서 어떻게 적용해야 하는지 알아보겠습니다.

     

    테넌트(Tenant)란?

    테넌트는 원래 "임차인"이라는 뜻입니다. 소프트웨어에서는 하나의 시스템을 사용하는 개별 고객 또는 조직을 의미합니다.

    예를 들어 Slack을 생각해보세요. A회사와 B회사 모두 Slack을 사용하지만, 서로의 메시지나 채널을 볼 수 없습니다. 여기서 A회사와 B회사가 각각 하나의 테넌트입니다.

    싱글 테넌트 vs 멀티 테넌트

    싱글 테넌트 (Single-Tenant)

    고객마다 완전히 분리된 인프라를 제공하는 방식입니다.

    장점

    • 완벽한 데이터 격리
    • 고객별 커스터마이징 용이
    • 한 고객의 장애가 다른 고객에게 영향 없음

    단점

    • 인프라 비용이 고객 수에 비례하여 증가
    • 운영 및 배포 복잡도 증가
    • 리소스 효율성 낮음

     

    멀티 테넌트 (Multi-Tenant)

    하나의 인프라를 여러 고객이 공유하는 방식입니다.

     

    장점

    • 인프라 비용 효율적
    • 운영 및 배포 단순화
    • 리소스 활용도 극대화

    단점

    • 데이터 격리에 주의 필요
    • Noisy Neighbor 문제 발생 가능
    • 테넌트별 커스터마이징 제한적

    멀티 테넌시 구현 전략

    멀티 테넌시를 구현하는 방법은 크게 세 가지로 나눌 수 있습니다. 각각 격리 수준과 비용 효율성의 트레이드오프가 있습니다.

    1. 데이터베이스 분리 (Database per Tenant)

    테넌트마다 별도의 데이터베이스를 사용합니다.

    특징

    • 격리 수준: ⭐⭐⭐⭐⭐ (최상)
    • 비용 효율: ⭐⭐ (낮음)
    • 복잡도: 중간

    적합한 경우

    • 규제가 엄격한 산업 (금융, 의료)
    • 고객이 데이터 격리를 강력히 요구하는 경우
    • 테넌트별 데이터 규모가 큰 경우

    2. 스키마 분리 (Schema per Tenant)

    하나의 데이터베이스 내에서 테넌트마다 별도의 스키마를 사용합니다.

    특징

    • 격리 수준: ⭐⭐⭐⭐ (높음)
    • 비용 효율: ⭐⭐⭐ (중간)
    • 복잡도: 중간

    적합한 경우

    • 적당한 수준의 격리가 필요한 경우
    • PostgreSQL 등 스키마를 잘 지원하는 DB 사용 시

    3. 테이블 공유 (Shared Table with Tenant ID)

    모든 테넌트가 동일한 테이블을 공유하고, tenant_id 컬럼으로 데이터를 구분합니다.

     

    -- 모든 테이블에 tenant_id 컬럼 추가
    CREATE TABLE users (
        id BIGINT PRIMARY KEY,
        tenant_id VARCHAR(50) NOT NULL,  -- 테넌트 식별자
        email VARCHAR(255) NOT NULL,
        name VARCHAR(100),
        created_at TIMESTAMP DEFAULT NOW(),
        INDEX idx_tenant (tenant_id)
    );
    
    -- 쿼리 시 항상 tenant_id 조건 포함
    SELECT * FROM users WHERE tenant_id = 'company_a' AND ...;

     

    특징

    • 격리 수준: ⭐⭐ (낮음)
    • 비용 효율: ⭐⭐⭐⭐⭐ (최상)
    • 복잡도: 낮음

    적합한 경우

    • 스타트업 초기 단계
    • 테넌트 수가 많고 데이터가 적은 경우
    • 빠른 개발이 필요한 경우

    구현 전략 비교표

    전략 격리 수준 비용 효율 확장성 운영 복잡도
    DB 분리 최상 낮음 중간
    스키마 분리 높음 중간 중간 중간
    테이블 공유 낮음 최상 높음 낮음

    실무에서 고려해야 할 핵심 포인트

    1. 테넌트 식별 (Tenant Resolution)

    요청이 들어왔을 때 어떤 테넌트인지 식별하는 방법입니다.

    1. 서브도메인 방식: company-a.myservice.com
    2. URL 경로 방식: myservice.com/company-a/...
    3. HTTP 헤더 방식: X-Tenant-ID: company-a
    4. JWT 토큰 방식: 토큰 내 tenant_id 클레임 포함

     

    2. 데이터 격리 보장

    테이블 공유 방식을 사용할 경우, 모든 쿼리에서 tenant_id 조건이 누락되지 않도록 주의해야 합니다.

    // 잘못된 예 - tenant_id 조건 누락
    public async Task<List<Asset>> GetAllAssets()
    {
        return await _context.Assets.ToListAsync(); // 위험!
    }
    
    // 올바른 예 - 항상 tenant_id 필터링
    public async Task<List<Asset>> GetAllAssets(string tenantId)
    {
        return await _context.Assets
            .Where(a => a.TenantId == tenantId)
            .ToListAsync();
    }

     

    ORM 레벨에서 Global Query Filter를 적용하면 실수를 방지할 수 있습니다.

    // Entity Framework Core - Global Query Filter
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Asset>()
            .HasQueryFilter(a => a.TenantId == _currentTenantId);
    }

     

    3. Noisy Neighbor 문제

    한 테넌트의 과도한 사용이 다른 테넌트에게 영향을 주는 문제입니다.

    해결 방안

    • 테넌트별 Rate Limiting 적용
    • 리소스 사용량 모니터링 및 알림
    • 테넌트별 Connection Pool 분리
    • 무거운 작업은 비동기 큐로 처리

    4. 테넌트별 설정 관리

    테넌트마다 다른 설정(로고, 테마, 기능 On/Off 등)을 관리해야 합니다.

     

    {
      "tenantId": "company_a",
      "settings": {
        "branding": {
          "logo": "https://...",
          "primaryColor": "#1E88E5"
        },
        "features": {
          "advancedReporting": true,
          "apiAccess": false
        },
        "limits": {
          "maxUsers": 100,
          "maxStorage": "10GB"
        }
      }
    }

     

    5. 테넌트별 과금 및 사용량 추적

    SaaS 비즈니스의 핵심입니다. 테넌트별로 다음을 추적해야 합니다.

    • API 호출 횟수
    • 스토리지 사용량
    • 활성 사용자 수
    • 특정 기능 사용량

    하이브리드 접근법

    실제 서비스에서는 단일 전략만 사용하기보다 하이브리드 방식을 많이 사용합니다.

     

    엔터프라이즈 고객에게는 별도 DB를, 일반 고객에게는 공유 테이블 방식을 적용하는 식입니다.

    마치며

    멀티 테넌시 아키텍처는 SaaS 서비스의 근간이 되는 설계 패턴입니다. 어떤 전략을 선택할지는 다음 요소를 종합적으로 고려해야 합니다.

    • 예상 테넌트 수와 성장 속도
    • 테넌트당 데이터 규모
    • 규제 및 컴플라이언스 요구사항
    • 개발 리소스와 일정
    • 비용 구조

    처음에는 테이블 공유 방식으로 시작하고, 서비스가 성장하면서 필요에 따라 격리 수준을 높여가는 것도 좋은 전략입니다. 중요한 것은 처음부터 테넌트 개념을 염두에 두고 설계하는 것입니다. 나중에 싱글 테넌트에서 멀티 테넌트로 전환하는 것은 매우 어렵습니다.

    반응형

    댓글

Designed by Tistory.