189. 멀티 테넌트 (Multi-Tenant) 데이터베이스 아키텍처
⚠️ 이 문서는 슬랙, 세일즈포스 같은 B2B SaaS(Software as a Service) 애플리케이션에서, 물리적인 서버나 데이터베이스 인스턴스는 하나만 띄워두고 수천 개의 서로 다른 고객사(Tenant) 데이터를 어떻게 안전하고 완벽하게 논리적으로 분리(Isolation)하여 수용할 것인가에 대한 데이터베이스 설계 패턴을 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 고객사마다 1개씩 서버와 DB를 따로 띄워주는 과거 구축형(On-Premises / Single-Tenant) 모델의 극악한 유지보수 비용을 없애기 위해, 하나의 거대한 통짜 아파트(DB)에 모든 고객을 몰아넣되 방음과 도어락(논리적 격리)을 확실하게 치는 공간 효율화 아키텍처다.
- 가치: 인프라 운영 비용을 극적으로 낮추고, 앱 버전 업데이트나 DB 스키마를 변경할 때 수천 개의 DB를 돌며 패치할 필요 없이 단 한 번의 배포로 모든 고객사 시스템을 일괄 업그레이드하는 압도적 민첩성을 확보한다.
- 기술 체계: '독립 DB 격리(Database per Tenant)', '스키마 분리(Schema per Tenant)', '단일 테이블 공유(Row-level Isolation)'라는 3단계 트레이드오프 모델이 있으며, 보안과 비용 절감 사이의 타협점을 찾는 것이 설계의 핵심이다.
Ⅰ. 싱글 테넌트의 비효율과 멀티 테넌트의 필요성
SaaS 사업을 하면서 고객마다 집을 지어주면 회사는 파산한다.
- 싱글 테넌시 (Single-Tenant)의 구조:
- A사, B사, C사가 가입할 때마다 AWS에 EC2 서버 1대와 RDS 인스턴스 1대씩을 매번 새로 찍어내어 전용으로 할당해 주는 구조다. (고립성 100%)
- 문제점: 1만 개의 고객사가 생기면 1만 개의 DB를 모니터링해야 한다. 1만 개의 서버가 평소에는 CPU 1%만 쓰며 놀고 있어도 요금을 내야 하고, DB 컬럼을 하나 추가(Migration)하려면 1만 개의 DB 스크립트를 며칠에 걸쳐 돌려야 한다 (유지보수 재앙).
- 멀티 테넌시 (Multi-Tenant)의 철학:
- 거대한 고성능 DB 서버 1대에 A사, B사, C사의 데이터를 몽땅 들이붓는다.
- 서버 자원을 '공유(Share)'하므로 노는 자원이 없이 100% 쥐어짤 수 있어 인프라 비용이 $1/100$로 줄어들며, SaaS 비즈니스의 막대한 영업이익률(마진)을 만들어내는 핵심 비결이 된다.
📢 섹션 요약 비유: 싱글 테넌트가 부자 고객 100명에게 각각 100채의 전원주택을 지어주고 보일러와 관리인을 100명 따로 두는 것이라면, 멀티 테넌트는 100세대짜리 거대한 고급 초고층 아파트를 지어놓고 중앙 집중식 난방과 관리사무소 하나로 모든 세대를 최고 효율로 관리하는 거대한 원가 절감 전략입니다.
Ⅱ. 멀티 테넌트 DB 설계의 3단계 패턴
비용을 아낄수록 고객 간의 분리는 허술해진다.
- 패턴 1: 데이터베이스 분리 (Database per Tenant):
- 물리적 DB 서버(RDS)는 1대지만, 그 안에 논리적인 Database(
CREATE DATABASE A_corp;)를 고객사 수만큼 수천 개 만드는 방식이다. - 장점: A사의 백업 데이터만 쏙 빼서 복원해 주기가 매우 쉽다. A사 데이터가 너무 커지면 그 DB만 통째로 다른 서버로 떼어내기(Sharding) 좋다.
- 단점: 연결(Connection Pool) 관리가 까다롭고, 스키마 변경 시 여전히 수천 개의 DB에 접속해 쿼리를 돌려야 한다.
- 물리적 DB 서버(RDS)는 1대지만, 그 안에 논리적인 Database(
- 패턴 2: 스키마 분리 (Schema per Tenant):
- 하나의 DB 안에, 고객사별로 Schema(또는 Oracle의 User)를 분리하여 테이블을 각각 생성하는 방식이다.
SELECT * FROM A_corp.users,SELECT * FROM B_corp.users처럼 호출. DB 관리의 편의성과 보안성 사이에서 가장 적당한 중간 타협점으로 널리 쓰인다.
- 패턴 3: 공유 테이블 분리 (Row-level Isolation):
- 가장 극단적이고 완전한 멀티 테넌시. 테이블 자체를 공유한다.
- 모든 고객의 데이터가 1개의
users테이블에 섞여 들어간다. 대신 모든 테이블의 1번 컬럼에 반드시tenant_id(A사, B사 식별자)를 박아 넣어야 한다. - 장점: 컬럼 추가, 백업 등 관리가 앱 1개 수준으로 극도로 편하고 서버 자원 효율이 가장 높다.
- 단점: 개발자가 SQL 쿼리를 짤 때 실수로
WHERE tenant_id = ?조건을 빼먹으면, A사 직원이 B사의 영업 비밀 데이터를 보게 되는 대형 정보유출(크로스 테넌트 오염) 참사가 발생한다. 백업 시 A사 데이터만 골라 복원하기도 매우 까다롭다.
📢 섹션 요약 비유: 데이터베이스 분리는 아파트에 세대별로 '독립된 방과 화장실(고립)'을 주는 것이고, 스키마 분리는 넓은 거실에 '파티션'만 쳐두는 것이며, 공유 테이블 분리는 벽조차 없이 수천 명의 사람이 한 강당에 모여 자되, 각자 이마에 포스트잇(tenant_id)으로 "101호 사람"이라고 적어두고 안 섞이길 기도하는 극한의 공간 쪼개기 방식입니다.
Ⅲ. 멀티 테넌트의 부작용: 노이지 네이버 (Noisy Neighbor)
공유의 비극은 누군가 자원을 독식할 때 터진다.
- 시끄러운 이웃 현상 (Noisy Neighbor):
- 가장 고도화된 '공유 테이블(패턴 3)'을 쓴다고 가정하자.
- A 고객사(삼성)가 연말 정산 배치를 돌리느라 엄청나게 무거운 쿼리를 날려 DB의 CPU 99%를 잡아먹어 버렸다.
- 그러자 같은 테이블, 같은 DB를 쓰고 있던 소규모 B 고객사, C 고객사 직원들이 화면을 넘길 때마다 10초씩 걸리는(Time-out) 치명적인 성능 간섭(Interference) 피해를 보게 된다.
- 극복 방안 (스로틀링과 격리):
- SaaS 애플리케이션 단(API Gateway)에서 테넌트별로 초당 호출 수(Rate Limit)를 엄격하게 제한하여 특정 고객이 자원을 독식하지 못하게 목줄(Throttling)을 채워야 한다.
- 또한, 엄청난 돈을 내는 초대형 VVIP 고객사는 공유 테이블에서 뽑아내어 싱글 테넌트(단독 서버)로 이사시켜 주는 하이브리드(Hybrid) 티어링 전략이 필수적이다.
📢 섹션 요약 비유: 아파트 거실의 공용 와이파이를 100세대가 나눠 쓰고 있는데, 101호 대학생이 넷플릭스 4K 영화를 5개 동시에 다운받는 바람에(Noisy Neighbor), 나머지 99세대가 카카오톡 메시지도 전송이 안 되어 분통을 터뜨리는 현상입니다. 관리사무소(SaaS)가 세대별 속도 제한(QoS)을 철저히 걸지 않으면 공유 모델은 폭동으로 끝납니다.