この記事では、最も文書化されている Postgres テナント モデル (共有スキーマ、テナントごとのベース、専用クラスタ、テナントごとのデータベースと共有データベースとも呼ばれる) を比較し、noisy neighborメカニズムについて説明し、Aurabase がプロビジョナー コードで検証された独自の 2 層モデルをどのように実装するかを詳しく説明します。パフォーマンス数値を公開する前に適用する手法については、 バックエンド ベンチマーク手法を参照してください。
2 つのクライアント (RLS、ポリシー、service_role) 間のデータ漏洩の問題を探している場合、これはこの記事の角度ではありません。RLS の比較と、プロジェクト による専用データベースでは、この論理的分離について詳しく説明しています。ここでは、物理リソース (CPU、IO、接続、キャッシュ) について話します。
必需品
- 共有データベースは必ずしも共有スキームであるとは限りません。Aurabase は、クラスタを共有するだけで、標準レベルであっても、各プロジェクトに独自の Postgres データベースを提供します。
noisy neighborは、データの機密性ではなく、物理リソース (CPU、IOPS、接続、自動バキューム) を低下させます。RLS はそれを解決しません。それは RLS の役割ではありません。- Aurabase プロビジョナーは、コードで検証された正確に 2 つのアーキテクチャにルーティングします:
FullyDedicated(プロジェクト用に予約された CNPG クラスター全体、エンタープライズ レベル) またはSharedClusterDedicated(組織の CNPG クラスター上の専用ベース。他の組織とは決して共有されません)。 - Aurabase フリートクラスタのデフォルトの観測容量しきい値はクラスタあたり 1000 ベースであり、構成可能ですが、これを超えると専用クラスタに移行することが推奨されます。
- 正しい選択は、「専用の方が常に良い」という反射的な考えではなく、実際の制約 (コンプライアンス、トラフィックの予測可能性、予算) によって決まります。
最も共有されたものから最も分離されたものまでの 3 つの Postgres 管理モデル
マルチテナント SaaS アプリケーションのアーキテクチャに関する Microsoft の公式ドキュメントでは、一般にサイロ (テナントごとの専用リソース)、プール (完全共有リソース)、およびブリッジ (2 つの混合、一部の分離テナントと他のテナントの共有) と呼ばれる 3 つのテナント モデルが区別されています。これら 3 つのモデルは、スキーマ、データベース、またはクラスター全体のレベルで Postgres に直接適用されます。
具体的には、Postgres バックエンドの場合、これにより 3 つの異なるアーキテクチャが提供されます。共有スキーマ (単一のベース、tenant_id列、行をフィルター処理する RLS ポリシー) は、マルチテナント ガイドで最も一般的なプール モデルです。経済的ですが、2 つのクライアント間の境界はテーブルごとに評価される SQL 式になります。共有クラスター上のテナントごとのベースは中間ブリッジ モデルです。各テナントには独自の Postgres ベース (実際の CREATE DATABASEコマンド) がありますが、複数のベースが同じ物理クラスター上に共存するため、CPU、IO、および接続を共有します。テナントごとに完全に専用のクラスターは完全なサイロ モデルです。CPU、RAM、IO リソースは完全に分離されており、通常は高いコンプライアンスや負荷の問題があるテナント用に予約されています。
| モデル | 資源絶縁 | 貯蔵用断熱材 | 運営上の労力 |
|---|---|---|---|
| 共有スキーマ (tenant_id + RLS) | なし | なし(共用テーブル) | 最小限(操作するベースは 1 つ) |
| テナントごとの共有クラスター | 部分的 (クラスター CPU/IO) | 合計(独自ベース) | 中程度 (N 塩基、1 クラスター) |
| テナントごとの完全専用クラスター | 合計 | 合計 | 高 (テナントあたり 1 クラスター) |
サイロ / プール / ブリッジの用語: Microsoft の公式ドキュメント、マルチテナント SaaS アーキテクチャ パターン (Azure Architecture Center)。
中間モデルである共有クラスター上のテナントごとのベースは、多くの場合、「全員に単一のベース」と「クライアントごとに 1 台のサーバー」の間の二者択一として選択肢を提示するガイドに記載されていません。ただし、これは Aurabase がデフォルトで使用するものであり、以下で詳しく説明します。
これら 3 つのモデルの選択は、BaaS プロバイダーだけでなく、あらゆるマルチテナント アーキテクチャの決定で生じます。マネージド Postgres (RDS、Cloud SQL、または自己ホスト型インスタンス) 上に独自の SaaS バックエンドを構築するチームは、複数のクライアントが同じ物理インスタンス上に配置されると、同じ競合メカニズムを実行して、まったく同じ調停を行います。
騒々しい隣人: リソースを共有すると何が悪化するか
noisy neighbor (ノイジー ネイバー) は、インフラストラクチャの共有リソースを不均衡に消費し、同じサーバー上の他のテナントに損害を与えるテナントです。この用語はパブリック クラウドに由来しますが、共有 Postgres クラスターに直接当てはまります。つまり、あるデータベースが、そのデータにまったく触れずに他のデータベースのパフォーマンスを低下させる可能性があります。
実稼働環境では、次の 6 つのメカニズムが最も頻繁に使用されます。
- CPU 競合: 負荷の高いクエリ (インデックスなしの結合、大量ソート) は、カーネルがクラスター内のすべてのアクティブなデータベース間で共有する CPU サイクルを消費します。
- IOPS 競合: バックアップ、
VACUUM FULL、または大量のインポートによりクラスターのディスク スループットが飽和し、他のデータベースへの読み取りと書き込みが遅くなります。 - 接続の枯渇:
max_connectionsは、ベースごとではなくクラスター全体のレベルでアクティブな接続の数を制限します。ベースが開きすぎると他の人のマージンが減ります。 - Autovacuum の競合: autovacuum はクラスターごとに限られた数のワーカーで実行されます。データベースの書き込み速度が高いと、別のデータベースのテーブルのクリーニングが遅れる可能性があります。
- キャッシュの削除:
shared_buffersはクラスター全体の単一メモリです。大規模なワーキング セットを持つデータベースは、隣接する小規模なデータベースのキャッシュされたページを削除する可能性があります。 - 共有メンテナンス ウィンドウ: バックアップ、レプリカ フェールオーバー、またはメジャー アップグレードは、ベースごとではなくクラスター全体に適用されます。
構造図であり、測定結果ではありません。これら 2 つのトポロジに関する比較パフォーマンスの数値は現在まで公表されていません。
多くの場合、接続バジェットは、レイテンシー以前であっても、運用環境で最も目に見える症状です。これは、 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 サイクル、接続スロット、ディスク スループットを予約しません。
2 つのテナントが完全に防水性の高い RLS ポリシーを持ち、同時に互いの性能を低下させる可能性があります。ノイジー ネイバーは物理リソースの問題であり、アクセス権の問題ではありません。この 2 つを混同すると、EPIRB が導入されると、運用上のセキュリティに対する誤った認識が生じます。
論理分離 (RLS ポリシー、 service_role、セキュリティ側のプロジェクト間の境界) については、専用記事 RLS とプロジェクトごとの専用ベース、Aurabase からのマルチテナント分離の選択を参照してください。この記事は物理的なリソースのレベルにとどまります。
コードで検証された Aurabase モデル
プロビジョナー コード (aura-provisioner) は、コードがタスク 12 として参照するプロビジョニング統合から、アクティブな Postgres プロジェクトで考えられる 2 つのアーキテクチャ ( FullyDedicated および SharedClusterDedicated) を文書化しています。従来のスキーマ粒度モデルはプロビジョニング パスから削除されました。
enterprise レベルは FullyDedicatedをトリガーします。これは、この単一プロジェクト用に予約された CNPG クラスター全体です。他のすべてのレベル (無料、プロ、チーム) は、プロジェクト組織の CNPG クラスター上の本格的な Postgres project_<uuid> データベースである SharedClusterDedicatedにルーティングされます。したがって、これは共有スキーマではありません。標準プランであっても、データベースは完全な Postgres データベースであり、共通テーブル内の 1 行ではありません。共有されるのはクラスター (CPU、RAM、ディスク、接続) であり、ベース自体ではありません。
組織の CNPG クラスターは、最初の Postgres プロジェクトがプロビジョニングされるときに作成され、別の組織のプロジェクトをホストすることはありません。設計上の選択はコード レベルでロックされています (org_cluster.rs、作成時に組織による Postgres アドバイザリー ロック)。したがって、共有 Aurabase ランディングで唯一考えられるうるさい隣人は、サードパーティ クライアントのプロジェクトではなく、自分の組織の別のプロジェクトです。
Aurabase が管理する PostgreSQL クラスタのアーキテクチャ仕様。
このクラスターあたり 1000 ベースのしきい値は、厳密な制限ではありません。これは、自動ブロックではなく、 FullyDedicatedへの移行の推奨をトリガーする可観測性ベンチマークです。これによって配置が決定されることはなくなり、組織ごとに 1 つのクラスターのみが可能になりました。
専用クラスターまたはフリートの各クラスターは、両方のトポロジーでアクティブな接続に対する圧力の一部を吸収する CNPG プーラー (PgBouncer) を公開します。このプーラーがリソース競合に対して実際に何を変更するかについては、以下で詳しく説明します。
共有クラスターの CPU/RAM サイズも組織間で均一ではありません。これは、すべてのレベルに適用される単一のサイズからではなく、専用の関数 (FleetSizing::from_org_plan、 org_cluster.rsで検証) を介して組織のレベルから派生します。チーム レベルの組織は、無料レベルの組織と同じ方法でクラスターのサイズを設定しません。
これら 2 つのアーキテクチャは、バージョン 17 ではなく PostgreSQL 16 で実行され、運用環境で使用される CNPG イメージの Dockerfile で検証されています。このバージョンの選択には独自のチューニングの影響があり、詳しくは Postgres 16 対 17 対 18 の比較を参照してください。
プーリングで十分な場合、専用が必要になる場合
プーリングは安っぽい妥協策ではありません。これは、開発、立ち上げ、または中程度の成長にある大部分のプロジェクトのトラフィックに相当します。この場合、専用クラスターは追加コストとなり、目に見えるメリットはありません。
| 信号 | 共有で十分です | 専用推奨 |
|---|---|---|
| 物理的隔離に関する正式な遵守 (健康、人事、公共部門) | いいえ | はい |
| 予測可能な交通量、適度なピーク | はい | |
| 予測不可能で持続的なピーク負荷 | 拘束の危険性 | はい |
| 予算は限られており、製品は検証段階にあります | はい | |
| 文書による絶縁を要求する契約条項 (DPA) | いいえ | はい |
文書化された物理的絶縁に対する契約上の義務の対象となるプロジェクトについては、DPA および コンプライアンス ページで各レベルの内容が詳しく説明されています。
Bytebase などのいくつかのスキーマ移行管理ツールによって強調される、テナントベース モデルの欠点は、技術的というよりは運用面にあります。各移行は、同じクラスター上に共存している場合でも、各ベースに 1 つずつ適用して検証する必要があります。完全に専用のクラスターでは、このコストが排除されず、さらにコストが追加されます。クラスターごとに 1 つの移行を 1 つだけではなく個別に監視する必要があります。
CodeOpinion などのマルチテナント ソフトウェア アーキテクチャに特化したリソースでは、共有スキームと完全専用クラスターの間の合理的な妥協点として、両極端の間の二者択一ではなく、この中間的なアプローチ (共有インフラストラクチャ上のテナントごと) を定期的に提示しています。
共有から専用への移行には、スキーマの書き換えやエンジンの変更は必要ありません。どちらの場合も、Supabase から Aurabase への移行ガイドで説明されているものと同じ pg_dump / pg_restore チェーンを備えた Postgres です。レベルの変更は、アプリケーションの書き換えではなく、トグル操作のままです。
よくある質問
覚えておくべきこと
専用ベースと共有ベースはデータ セキュリティに関して競合しません。どちらのモデルも論理レベルで 1 つのテナントを別のテナントから正しく分離できます。これらは、物理リソース (CPU、IOPS、接続、キャッシュ、メンテナンス ウィンドウ) に関して互いに対立します。ノイジーネイバーを定義するのはこの計画であり、不適切に作成された RLS ポリシーではありません。
プロビジョナーコードで検証された Aurabase モデルは、デフォルトで中間的な妥協点を保持しています。つまり、プロジェクトごとに専用の Postgres データベースが共有クラスター上にあり、単一組織用に厳密に予約され、ビジネス レベル用に予約された完全専用クラスターです。正しい選択は、専用が常に最良の選択肢であるという反射的なものではなく、実際の制約に依存します。