이 문서에서는 가장 많이 문서화된 Postgres 테넌시 모델(공유 스키마, 테넌트 기반별, 전용 클러스터, 테넌트별 데이터베이스와 공유 데이터베이스라고도 함)을 비교하고 noisy neighbor메커니즘을 설명한 다음 Aurabase가 프로비저너 코드에서 검증된 자체 2계층 모델을 구현하는 방법을 자세히 설명합니다. 성능 수치를 게시하기 전에 적용하는 방법론은 백엔드 벤치마크 방법론을 참조하세요.
두 클라이언트(RLS, 정책, service_role) 간의 데이터 유출 문제를 찾고 있다면 이 기사의 각도가 아닙니다. RLS 비교 및 프로젝트의 전용 데이터베이스가 이 논리적 격리를 자세히 다루고 있습니다. 여기서는 CPU, IO, 연결, 캐시와 같은 물리적 리소스에 대해 이야기하고 있습니다.
필수사항
- 공유 데이터베이스가 반드시 공유 방식일 필요는 없습니다. Aurabase는 표준 수준에서도 클러스터만 공유하여 각 프로젝트에 자체 Postgres 데이터베이스를 제공합니다.
noisy neighbor는 데이터 기밀성이 아닌 물리적 리소스(CPU, IOPS, 연결, autovacuum)를 저하시킵니다. RLS는 이를 해결하지 않으며 이는 RLS의 역할이 아닙니다.- Aurabase 프로비저너는 코드에서 확인된 정확히 두 개의 아키텍처, 즉
FullyDedicated(프로젝트, 엔터프라이즈 수준용으로 예약된 전체 CNPG 클러스터) 또는SharedClusterDedicated(조직의 CNPG 클러스터에 대한 전용 기반, 다른 조직과 공유되지 않음)로 라우팅합니다. - Aurabase 플릿 클러스터에는 클러스터당 1000개 베이스라는 기본 관찰 용량 임계값이 있으며 구성 가능하며 그 이상에서는 전용 클러스터로 마이그레이션하는 것이 좋습니다.
- 올바른 선택은 "전용이 항상 더 낫다"는 생각이 아니라 실제 제약 조건(규정 준수, 트래픽 예측 가능성, 예산)에 따라 달라집니다.
가장 많이 공유되는 것부터 가장 고립된 것까지 세 가지 Postgres 관리 모델
다중 테넌트 SaaS 애플리케이션의 아키텍처에 대한 Microsoft의 공식 문서에서는 일반적으로 Silo(테넌트당 전용 리소스), Pool(완전히 공유되는 리소스) 및 Bridge(둘의 혼합, 일부는 격리된 테넌트, 다른 일부는 공유됨)라고 하는 세 가지 테넌트 모델을 구별합니다. 이 세 가지 모델은 스키마, 데이터베이스 또는 전체 클러스터 수준에서 Postgres에 직접 적용됩니다.
구체적으로 Postgres 백엔드의 경우 이는 세 가지 고유한 아키텍처를 제공합니다. 공유 스키마(단일 기본, tenant_id열, 행을 필터링하는 RLS 정책)는 다중 테넌트 가이드에서 가장 일반적인 풀 모델입니다. 경제적이지만 두 클라이언트 사이의 경계는 테이블별로 평가되는 SQL 표현식이 됩니다. 공유 클러스터의 테넌트별 기본은 중간 브리지 모델입니다. 각 테넌트에는 자체 Postgres 기본(실제 CREATE DATABASE명령)이 있지만 여러 기본이 동일한 물리적 클러스터에 공존하므로 CPU, IO 및 연결을 공유합니다. 테넌트별 완전 전용 클러스터는 완전한 사일로 모델입니다. 완전히 격리된 CPU, RAM 및 IO 리소스는 일반적으로 높은 규정 준수 또는 로드 문제가 있는 테넌트를 위해 예약됩니다.
| 모델 | 자원절연 | 보관 단열 | 운영 노력 |
|---|---|---|---|
| 공유 스키마(tenant_id + RLS) | 없음 | 없음(공용테이블) | 최소(작동 베이스 1개) |
| 테넌트 기준, 공유 클러스터 | 부분(클러스터 CPU/IO) | 합계(자체기준) | 보통(N개 염기, 1개 클러스터) |
| 테넌트당 완전 전용 클러스터 | 합계 | 합계 | 높음(테넌트당 클러스터 1개) |
사일로/풀/브리지 용어: 공식 Microsoft 설명서, 다중 테넌트 SaaS 아키텍처 패턴(Azure Architecture Center).
공유 클러스터의 테넌트별 기반인 중간 모델은 "모든 사람을 위한 단일 기반"과 "클라이언트당 하나의 서버" 사이의 바이너리 선택을 제시하는 가이드에 없는 경우가 많습니다. 그러나 이는 Aurabase가 기본적으로 사용하는 것입니다. 아래에 자세히 설명되어 있습니다.
이 세 가지 모델 사이의 선택은 BaaS 제공업체뿐만 아니라 모든 다중 테넌트 아키텍처 결정에서 발생합니다. 관리형 Postgres(RDS, Cloud SQL 또는 자체 호스팅 인스턴스)에서 자체 SaaS 백엔드를 구축하는 팀은 여러 클라이언트가 동일한 물리적 인스턴스에 배치되면 동일한 경합 메커니즘을 사용하여 정확히 동일한 중재를 수행합니다.
시끄러운 이웃: 자원이 공유될 때 악화되는 것
noisy neighbor(시끄러운 이웃)는 인프라 공유 리소스의 불균형한 공유를 소비하여 동일한 서버의 다른 테넌트에 해를 끼치는 테넌트입니다. 이 용어는 퍼블릭 클라우드에서 유래했지만 공유 Postgres 클러스터에 직접 적용됩니다. 즉, 하나의 데이터베이스는 데이터를 건드리지 않고도 다른 데이터베이스의 성능을 저하시킬 수 있습니다.
프로덕션 환경에서 가장 자주 나타나는 여섯 가지 메커니즘은 다음과 같습니다.
- CPU 경합: 비용이 많이 드는 쿼리(인덱스 없는 조인, 대규모 정렬)는 커널이 클러스터의 모든 활성 데이터베이스 간에 공유하는 CPU 주기를 소비합니다.
- IOPS 경합: 백업,
VACUUM FULL또는 대량 가져오기는 클러스터의 디스크 처리량을 포화시켜 다른 데이터베이스에 대한 읽기 및 쓰기 속도를 저하시킵니다. - 연결 소모:
max_connections는 기본 단위가 아닌 전체 클러스터 수준에서 활성 연결 수를 제한합니다. 너무 많이 열리는 베이스는 다른 사람들의 마진을 감소시킵니다. - Autovacuum 경합: autovacuum은 클러스터당 제한된 수의 작업자로 실행됩니다. 쓰기 속도가 높은 데이터베이스는 다른 데이터베이스의 테이블 정리를 지연시킬 수 있습니다.
- 캐시 제거:
shared_buffers는 전체 클러스터에 대한 단일 메모리입니다. 대규모 작업 세트가 있는 데이터베이스는 더 작은 인접 데이터베이스의 캐시된 페이지를 제거할 수 있습니다. - 공유 유지 관리 기간: 백업, 복제본 장애 조치 또는 주요 업그레이드가 기본 단위가 아닌 전체 클러스터에 적용됩니다.
측정 결과가 아닌 구조 다이어그램: 이 두 토폴로지에 대해 현재까지 공개된 비교 성능 수치는 없습니다.
연결 예산은 대기 시간 이전에도 프로덕션에서 가장 눈에 띄는 증상인 경우가 많습니다. 이는 max_connections 튜닝 가이드 및 비교 PgBouncer, Supavisor 및 PgCat의 세부 주제입니다.
A transaction mode pooler (PgBouncer, Supavisor, PgCat) mitigates connection exhaustion, but does not remove CPU or IOPS contention: it reuses existing server connections, it does not add additional CPU cores or disk throughput to the cluster. Our article on transaction pooling mode details what this mode actually changes, and what it doesn't change.
RLS는 리소스가 아닌 데이터를 격리합니다.
행 수준 보안은 다른 문제를 해결합니다. 즉, 쿼리가 논리적 수준에서 다른 테넌트의 행을 읽거나 수정하는 것을 방지합니다. 특정 테넌트에 대해 CPU 주기, 연결 슬롯, 디스크 처리량을 예약하지 않습니다.
두 테넌트가 완벽하게 방수 RLS 정책을 갖고 동시에 서로의 성능을 저하시킬 수 있습니다. 시끄러운 이웃은 액세스 권한이 아닌 물리적 리소스의 문제입니다. 두 가지를 혼동하면 EPIRB가 설치되면 운영 보안에 대한 잘못된 인식이 생깁니다.
논리적 격리(RLS 정책, service_role, 보안 측면의 프로젝트 간 경계)에 대해서는 전용 기사인 RLS 및 프로젝트별 전용 베이스, Aurabase에서 다중 테넌트 격리 선택을 참조하세요. 이 글은 물리적 자원 수준에 머물고 있습니다.
코드로 검증된 Aurabase 모델
프로비저너 코드(aura-provisioner)는 코드가 작업 12로 참조하는 프로비저닝 통합에서 활성 Postgres 프로젝트에 대해 가능한 두 가지 아키텍처( FullyDedicated 및 SharedClusterDedicated)를 정확히 문서화합니다. 레거시 스키마 기반 모델이 프로비저닝 경로에서 제거되었습니다.
enterprise 수준은 이 단일 프로젝트용으로 예약된 전체 CNPG 클러스터인 FullyDedicated를 트리거합니다. 다른 모든 레벨(무료, 프로, 팀)은 프로젝트 조직의 CNPG 클러스터에 있는 완전한 Postgres project_<uuid> 데이터베이스인 SharedClusterDedicated로 라우팅됩니다. 따라서 이는 공유 스키마가 아닙니다. 표준 계획에서도 데이터베이스는 공통 테이블의 한 줄이 아닌 완전한 Postgres 데이터베이스입니다. 공유되는 것은 베이스 자체가 아닌 클러스터(CPU, RAM, 디스크, 연결)입니다.
조직의 CNPG 클러스터는 첫 번째 Postgres 프로젝트가 프로비저닝될 때 생성되며 다른 조직의 프로젝트를 호스팅하지 않습니다. 설계 선택은 코드 수준에서 잠겨 있습니다(org_cluster.rs, 생성 시 조직별 Postgres 자문 잠금). 따라서 공유 Aurabase 착륙장에서 소음이 발생할 수 있는 유일한 이웃은 제3자 클라이언트의 프로젝트가 아닌 자신의 조직의 또 다른 프로젝트입니다.
Aurabase 관리형 PostgreSQL 클러스터 아키텍처 사양.
클러스터당 1000개 베이스라는 임계값은 엄격한 제한이 아닙니다. 이는 자동 차단이 아닌 FullyDedicated로 마이그레이션하라는 권장 사항을 트리거하는 관찰 가능성 벤치마크입니다. 더 이상 배치 결정을 내리지 않으며 이제 조직당 하나의 클러스터만 가능합니다.
전용 또는 플릿의 각 클러스터는 두 토폴로지 모두에서 활성 연결에 대한 압력의 일부를 흡수하는 CNPG 풀러(PgBouncer)를 노출합니다. 이 풀러가 리소스 경합에 대해 실제로 변경하는 사항은 아래에 자세히 설명되어 있습니다.
공유 클러스터의 CPU/RAM 크기도 조직 간에 균일하지 않습니다. 이는 모든 수준에 적용되는 단일 크기가 아니라 전용 기능(FleetSizing::from_org_plan, org_cluster.rs에서 확인됨)을 통해 조직 수준에서 파생됩니다. 팀 수준의 조직은 무료 수준의 조직과 동일한 방식으로 클러스터 크기를 조정하지 않습니다.
이 두 아키텍처는 버전 17이 아닌 PostgreSQL 16에서 실행되며 프로덕션에 사용되는 CNPG 이미지의 Dockerfile에서 확인됩니다. 이러한 버전 선택에는 Postgres 16 대 17 대 18 비교에 자세히 설명된 자체 조정 의미가 있습니다.
풀링으로 충분할 때, 전용이 필요할 때
풀링은 값싼 타협이 아닙니다. 이는 개발, 출시 또는 적당한 성장 중인 대다수 프로젝트의 트래픽에 해당하며, 여기서 전용 클러스터는 측정 가능한 이점 없이 추가 비용이 발생합니다.
| 신호 | 공유하면 충분하다 | 전용 권장 |
|---|---|---|
| 물리적 격리에 대한 공식 준수(보건, HR, 공공 부문) | 아니요 | 예 |
| 예측 가능한 교통량, 적당한 피크 | 예 | |
| 예측 불가능하고 지속적인 최대 부하 | 구속의 위험 | 예 |
| 예산 부족, 제품 검증 단계 | 예 | |
| 문서화된 단열을 요구하는 계약 조항(DPA) | 아니요 | 예 |
문서화된 물리적 단열에 대한 계약상 의무가 적용되는 프로젝트의 경우 DPA 및 규정 준수 페이지에서 각 수준이 다루는 내용을 자세히 설명합니다.
Bytebase와 같은 여러 스키마 마이그레이션 관리 도구에서 강조된 기본별 모델의 단점은 기술적인 것이 아니라 운영적인 것입니다. 각 마이그레이션은 동일한 클러스터에 공존하는 경우에도 각 베이스에 하나씩 적용하고 확인해야 합니다. 완전 전용 클러스터는 이러한 비용을 없애지는 못하지만 추가하기까지 합니다. 즉, 하나가 아닌 독립적으로 모니터링하기 위해 클러스터당 하나의 마이그레이션을 추가하는 것입니다.
CodeOpinion과 같은 다중 테넌트 소프트웨어 아키텍처를 전문으로 하는 리소스는 이 중간 접근 방식(공유 인프라의 테넌트 기준)을 두 극단 사이의 바이너리 선택이 아니라 공유 체계와 완전 전용 클러스터 간의 합리적인 절충안으로 정기적으로 제시합니다.
공유에서 전용으로 전환하는 데에는 스키마를 다시 작성하거나 엔진을 변경할 필요가 없습니다. 두 경우 모두 Supabase에서 Aurabase로의 마이그레이션 가이드에 설명된 것과 동일한 pg_dump / pg_restore 체인을 사용하는 Postgres입니다. 수준 변경은 애플리케이션 재작성이 아닌 토글 작업으로 유지됩니다.
자주 묻는 질문
기억해야 할 것
전용 베이스와 공유 베이스는 데이터 보안 측면에서 충돌하지 않습니다. 두 모델 모두 논리적 수준에서 하나의 테넌트를 다른 테넌트로부터 올바르게 격리할 수 있습니다. 물리적 리소스(CPU, IOPS, 연결, 캐시, 유지 관리 기간)에서 서로 반대됩니다. 잘못 작성된 RLS 정책이 아니라 시끄러운 이웃을 정의하는 것은 바로 이 계획입니다.
프로비저너 코드에서 검증된 Aurabase 모델은 기본적으로 중간 절충안을 유지합니다. 즉, 프로젝트당 전용 Postgres 데이터베이스는 공유 클러스터에 있지만 단일 조직용으로 엄격하게 예약되어 있으며 완전히 전용 클러스터는 비즈니스 수준용으로 예약되어 있습니다. 올바른 선택은 헌신적인 선택이 항상 최선의 선택이 되는 반사 작용이 아니라 실제 제약 조건에 달려 있습니다.