

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# PostgreSQL のマルチテナント SaaS パーティショニングモデル
<a name="partitioning-models"></a>

マルチテナンシーを実現する最善の方法は、SaaS アプリケーションの要件によって異なります。以下のセクションでは、PostgreSQL でマルチテナンシーを正常に実装するためのパーティショニングモデルを示します。

**注記**  
このセクションで説明するモデルは、Amazon RDS for PostgreSQL と Aurora PostgreSQL 互換の両方に適用されます。このセクションの *PostgreSQL* への参照は、両方のサービスに適用されます。

PostgreSQL for SaaS パーティショニングで使用できる高レベルモデルは、サイロ、ブリッジ、プールの 3 つです。次の図は、サイロモデルとプールモデル間のトレードオフをまとめたものです。ブリッジモデルは、サイロモデルとプールモデルのハイブリッドです。


****  

| **パーティショニングモデル** | **利点** | **欠点** | 
| --- | --- | --- | 
| サイロ | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | 
| プール | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | 
| ブリッジ | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/partitioning-models.html) | 

以下のセクションでは、各モデルについて詳しく説明します。

**Topics**
+ [PostgreSQL サイロモデル](silo.md)
+ [PostgreSQL プールモデル](pool.md)
+ [PostgreSQL ブリッジモデル](bridge.md)
+ [ディシジョンマトリックス](matrix.md)

# PostgreSQL サイロモデル
<a name="silo"></a>

サイロモデルは、アプリケーションのテナントごとに PostgreSQL インスタンスをプロビジョニングすることで実装されます。サイロモデルはテナントのパフォーマンスとセキュリティの分離に優れ、*ノイズの多い近隣*現象を完全に排除します。ノイズの多い近隣現象は、あるテナントのシステムの使用が別のテナントのパフォーマンスに影響を与える場合に発生します。サイロモデルを使用すると、各テナントに固有のパフォーマンスを調整し、停止を特定のテナントのサイロに制限できます。ただし、一般的にサイロモデルの採用を促進するのは、厳格なセキュリティと規制の制約です。これらの制約は、SaaS のお客様が動機付けることができます。たとえば、SaaS のお客様は、内部の制約によりデータを分離することを要求する場合があり、SaaS プロバイダーはそのようなサービスを追加料金で提供する場合があります。

 ![\[SaaS PostgreSQL silo model\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/images/saas-postgresql-silo.png) 

サイロモデルは特定のケースで必要になる場合がありますが、多くの欠点があります。複数の PostgreSQL インスタンス間でのリソース消費の管理は複雑になる可能性があるため、多くの場合、サイロモデルをコスト効率の高い方法で使用することは困難です。さらに、このモデルのデータベースワークロードの分散性により、テナントアクティビティを一元的に把握することが困難になります。独立して運用される多数のワークロードを管理すると、運用と管理のオーバーヘッドが増加します。また、サイロモデルでは、テナント固有のリソースをプロビジョニングする必要があるため、テナントのオンボーディングがより複雑で時間がかかります。さらに、テナント固有の PostgreSQL インスタンスの数が増えるにつれて管理にかかる運用時間が長くなるため、SaaS システム全体のスケーリングが難しくなる可能性があります。最後の考慮事項は、アプリケーションまたはデータアクセスレイヤーが関連する PostgreSQL インスタンスへのテナントのマッピングを維持する必要があることです。これにより、このモデルの実装が複雑になります。

# PostgreSQL プールモデル
<a name="pool"></a>

プールモデルは、単一の PostgreSQL インスタンス (Amazon RDS または Aurora) をプロビジョニングし、[行レベルのセキュリティ (RLS)](https://aws.amazon.com/blogs/database/multi-tenant-data-isolation-with-postgresql-row-level-security/) を使用してテナントデータの分離を維持することによって実装されます。RLS ポリシーは、`SELECT`クエリによって返されるテーブル内の行、または `INSERT`、、`UPDATE`および `DELETE` コマンドによって影響を受ける行を制限します。プールモデルは、すべてのテナントデータを 1 つの PostgreSQL スキーマに一元化するため、コスト効率が大幅に向上し、維持する運用オーバーヘッドが少なくなります。このソリューションのモニタリングも、一元化により大幅に簡素化されます。ただし、プールモデルでテナント固有の影響をモニタリングするには、通常、アプリケーションで追加の計測が必要です。これは、デフォルトで PostgreSQL はどのテナントがリソースを消費しているかを認識しないためです。新しいインフラストラクチャが不要なため、テナントのオンボーディングが簡素化されます。この俊敏性により、テナントオンボーディングワークフローの迅速で自動化された実行が容易になります。

 ![\[SaaS PostgreSQL pool model\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/images/saas-postgresql-pool.png) 

プールモデルは一般的にコスト効率が高く、管理が容易ですが、いくつかの欠点があります。ノイズの多い近隣現象をプールモデルで完全に排除することはできません。ただし、PostgreSQL インスタンスで適切なリソースを利用できるようにし、クエリをリードレプリカや Amazon ElastiCache にオフロードするなど、PostgreSQL の負荷を軽減するための戦略を使用することで軽減できます。アプリケーション計測はテナント固有のアクティビティをログに記録してモニタリングできるため、効果的なモニタリングはテナントのパフォーマンス分離の懸念への対応にも役立ちます。最後に、一部の SaaS のお客様は、RLS が提供する論理的な分離で十分ではないと判断し、追加の分離対策を要求する場合があります。

# PostgreSQL ブリッジモデル
<a name="bridge"></a>

PostgreSQL ブリッジモデルは、プールされたアプローチとサイロ化されたアプローチの組み合わせです。プールされたモデルと同様に、テナントごとに 1 つの PostgreSQL インスタンスをプロビジョニングします。テナントデータの分離を維持するには、PostgreSQL 論理コンストラクトを使用します。次の図では、PostgreSQL データベースを使用してデータを論理的に分離しています。

**注記**  
PostgreSQL データベースは、個別の Amazon RDS for PostgreSQL または Aurora PostgreSQL 互換 DB インスタンスを参照しません。代わりに、PostgreSQL データベース管理システムの論理構造を参照してデータを分離します。

 ![\[SaaS PostgreSQL bridge model with separate databases\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/images/saas-postgresql-bridge-dbs.png) 

次の図に示すように、各データベースにテナント固有のスキーマを持つ単一の PostgreSQL データベースを使用してブリッジモデルを実装することもできます。

 ![\[SaaS PostgreSQL bridge model with separate schemas\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/saas-multitenant-managed-postgresql/images/saas-postgresql-bridge-schemas.png) 

ブリッジモデルは、プールモデルと同じノイズの多い近隣とテナントのパフォーマンス分離の懸念に悩まされています。また、テナントごとに個別のデータベースまたはスキーマをプロビジョニングする必要があるため、運用およびプロビジョニングのオーバーヘッドも追加されます。テナントのパフォーマンスの懸念に迅速に対応するためには、効果的なモニタリングが必要です。また、テナント固有の使用状況をモニタリングするには、アプリケーション計測も必要です。全体として、ブリッジモデルは RLS の代替として見ることができます。これにより、新しい PostgreSQL データベースまたはスキーマが必要になるため、テナントのオンボーディング作業がわずかに強化されます。サイロモデルと同様に、アプリケーションまたはデータアクセスレイヤーは、関連する PostgreSQL データベースまたはスキーマへのテナントのマッピングを維持する必要があります。

# ディシジョンマトリックス
<a name="matrix"></a>

PostgreSQL で使用するマルチテナント SaaS パーティショニングモデルを決定するには、次の決定マトリックスを参照してください。マトリックスは、次の 4 つのパーティショニングオプションを分析します。
+ Silo – テナントごとに個別の PostgreSQL インスタンスまたはクラスター。
+ 個別のデータベースとのブリッジ — 単一の PostgreSQL インスタンスまたはクラスター内のテナントごとに個別のデータベース。
+ 個別のスキーマを使用したブリッジ — 単一の PostgreSQL データベース内のテナントごとに、単一の PostgreSQL インスタンスまたはクラスター内の個別のスキーマ。
+ プール – 1 つのインスタンスとスキーマ内のテナントの共有テーブル。


****  

| **** | **サイロ** | **個別のデータベースとブリッジする** | **個別のスキーマでブリッジする** | **プール** | 
| --- | --- | --- | --- | --- | 
| ユースケース | リソースの使用を完全に制御してデータを分離することが重要な要件であるか、非常に大規模でパフォーマンス重視のテナントがあります。 | データの分離は重要な要件であり、テナントのデータの制限付きまたは相互参照は必要ありません。 | データ量が中程度のテナントの数。これは、テナントのデータを相互参照する必要がある場合に推奨されるモデルです。 | テナントあたりのデータが少ない多数のテナント。 | 
| 新しいテナントオンボーディングの俊敏性 | 非常に遅い。(テナントごとに新しいインスタンスまたはクラスターが必要です）。 | 中程度に遅い。(スキーマオブジェクトを保存するには、テナントごとに新しいデータベースを作成する必要があります）。 | 中程度に遅い。(オブジェクトを保存するには、テナントごとに新しいスキーマを作成する必要があります）。 | 最速オプション。(最小限のセットアップが必要です）。 | 
| データベース接続プールの設定作業と効率 | 多大な労力が必要です。(テナントごとに 1 つの接続プール。) 効率が低下します。(テナント間のデータベース接続共有はありません）。 | 多大な労力が必要です。([Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html) を使用しない限り、テナントごとに 1 つの接続プール設定。)  効率が低下します。(テナント間のデータベース接続共有と接続の合計数。 すべてのテナントでの使用は、DB インスタンスクラスに基づいて制限されます。) | 必要な労力が減ります。(すべてのテナントに 1 つの接続プール設定。)  ある程度効率的です。(セッションプールモードでの `SET ROLE`または `SET SCHEMA` コマンドによる接続の再利用のみ。 `SET` コマンドは Amazon RDS Proxy の使用時にセッションピン留めも引き起こしますが、クライアント接続プールは削除でき、効率を高めるためにリクエストごとに直接接続できます）。 | 最小労力が必要。 最も効率的です。(すべてのテナントに 1 つの接続プールがあり、すべてのテナント間で接続を効率的に再利用できます。 データベース接続の制限は DB インスタンスクラスに基づいています）。 | 
| データベースメンテナンス ([バキューム管理](https://www.postgresql.org/docs/current/routine-vacuuming.html)) とリソースの使用 | よりシンプルな管理。 | 中程度の複雑さ。( の後にデータベースごとにバキュームワーカーを起動する必要があり、自動バキュームランチャーの CPU 使用率が高くなるためvacuum\$1naptime、リソースの消費量が高くなる可能性があります。 また、各データベースの PostgreSQL システムカタログテーブルのバキューム処理に関連する追加のオーバーヘッドが発生する場合もあります）。 | 大規模な PostgreSQL システムカタログテーブル。(テナント数とリレーション数に応じて、合計pg\$1catalogサイズは数十 GBs です。 テーブルの肥大化を制御するために、バキューム関連のパラメータの変更が必要になる可能性があります。) | テナントの数とテナントあたりのデータによっては、テーブルが大きい場合があります。(テーブルの肥大化を制御するためにバキューム関連のパラメータを変更する必要がある可能性があります）。 | 
| 拡張機能の管理作業 | 多大な労力 (個別のインスタンス内のデータベースごと）。 | 多大な労力 (各データベースレベル）。 | 最小労力 (共通データベースで 1 回）。 | 最小労力 (共通データベースで 1 回）。 | 
| デプロイの労力を変更する | 多大な労力。(各インスタンスに接続し、変更をロールアウトします）。 | 多大な労力。(各データベースとスキーマに接続し、変更をロールアウトします）。 | 中程度の労力。(共通データベースに接続し、スキーマごとに変更をロールアウトします）。 | 最小限の労力。(共通データベースに接続し、変更をロールアウトします）。 | 
| デプロイの変更 – 影響範囲 | 最小。(影響を受ける単一テナント) | 最小。(影響を受ける単一テナント) | 最小。(影響を受ける単一テナント) | 非常に大きい。(影響を受けるすべてのテナント）。 | 
| クエリパフォーマンスの管理と労力 | 管理可能なクエリパフォーマンス。 | 管理可能なクエリパフォーマンス。 | 管理可能なクエリパフォーマンス。 | クエリのパフォーマンスを維持するには、かなりの労力が必要になる可能性があります。(時間の経過とともに、テーブルのサイズが大きくなるため、クエリの実行が遅くなる可能性があります。 テーブルパーティショニングとデータベースシャーディングを使用してパフォーマンスを維持できます）。 | 
| クロステナントリソースへの影響 | 影響なし。(テナント間のリソース共有はありません）。 | 中程度の影響。(テナントは、インスタンス CPU やメモリなどの共通リソースを共有します）。 | 中程度の影響。(テナントは、インスタンス CPU やメモリなどの共通リソースを共有します）。 | 大きな影響。(テナントは、リソース、ロックの競合などの観点から相互に影響します）。 | 
| テナントレベルの調整 (テナントごとの追加インデックスの作成や、特定のテナントの DB パラメータの調整など) | 可能です。 | ある程度可能。(スキーマレベルの変更はテナントごとに行うことができますが、データベースパラメータはすべてのテナントでグローバルです）。 | ある程度可能。(スキーマレベルの変更はテナントごとに行うことができますが、データベースパラメータはすべてのテナントでグローバルです）。 | できません。(テーブルはすべてのテナントによって共有されます）。 | 
| パフォーマンス重視のテナントの労力を再調整する | 最小。(再調整する必要はありません。 このシナリオを処理するためにサーバーと I/O リソースをスケールします。) | 中程度。(論理レプリケーションまたは を使用してデータベースをpg\$1dumpエクスポートしますが、データサイズによってはダウンタイムが長くなる場合があります。 Amazon RDS for PostgreSQL のトランスポータブルデータベース機能を使用すると、インスタンス間でデータベースをすばやくコピーできます。) | 中程度ですが、ダウンタイムが長くなる可能性があります。(論理レプリケーションまたは を使用してスキーマをエクスポートpg\$1dumpしますが、データサイズによってはダウンタイムが長くなる場合があります）。 | すべてのテナントが同じテーブルを共有するため、重要です。(データベースをシャーディングするには、すべてを別のインスタンスにコピーし、テナントデータをクリーンアップするための追加のステップが必要です）。 ほとんどの場合、アプリケーションロジックの変更が必要です。 | 
| メジャーバージョンアップグレードのデータベースのダウンタイム | 標準のダウンタイム。(PostgreSQL システムカタログサイズによって異なります）。 | ダウンタイムが長くなる可能性があります。(システムカタログのサイズによって、時間は異なります。 PostgreSQL システムカタログテーブルもデータベース間で複製されます) | ダウンタイムが長くなる可能性があります。(PostgreSQL システムカタログのサイズによって、時間は異なります）。 | 標準のダウンタイム。(PostgreSQL システムカタログサイズによって異なります）。 | 
| 管理オーバーヘッド (データベースログ分析やバックアップジョブのモニタリングなど) | 多大な労力 | 最小限の労力。 | 最小限の労力。 | 最小限の労力。 | 
| テナントレベルの可用性 | 最高。(各テナントは失敗し、個別に復旧します）。 | 影響範囲の拡大。(ハードウェアまたはリソースの問題が発生した場合、すべてのテナントが失敗し、一緒に復旧します）。 | 影響範囲の拡大。(ハードウェアまたはリソースの問題が発生した場合、すべてのテナントが失敗し、一緒に復旧します）。 | 影響範囲の拡大。(ハードウェアまたはリソースの問題が発生した場合、すべてのテナントが失敗し、一緒に復旧します）。 | 
| テナントレベルのバックアップと復旧の労力 | 最小労力。(各テナントは個別にバックアップおよび復元できます）。 | 中程度の労力。(テナントごとに論理エクスポートとインポートを使用します。 一部のコーディングと自動化が必要です）。 | 中程度の労力。(テナントごとに論理エクスポートとインポートを使用します。 一部のコーディングと自動化が必要です）。 | 多大な労力。(すべてのテナントが同じテーブルを共有します）。 | 
| テナントレベルのpoint-in-timeリカバリの労力 | 最小限の労力。(スナップショットを使用してポイントインタイムリカバリを使用するか、Amazon Aurora でバックトラックを使用します）。 | 中程度の労力。(スナップショットの復元、エクスポート/インポートを使用します。 ただし、これはスローオペレーションになります）。 | 中程度の労力。(スナップショットの復元、エクスポート/インポートを使用します。 ただし、これはスローオペレーションになります）。 | 多大な労力と複雑さ。 | 
| 統一スキーマ名 | テナントごとに同じスキーマ名。 | テナントごとに同じスキーマ名。 | テナントごとに異なるスキーマ。 | 共通スキーマ。 | 
| テナントごとのカスタマイズ (特定のテナントの追加テーブル列など) | 可能。 | 可能。 | 可能。 | 複雑 (すべてのテナントが同じテーブルを共有するため）。 | 
| オブジェクトリレーショナルマッピング (ORM) レイヤーでのカタログ管理効率 (Ruby など) | 効率的 (クライアント接続はテナントに固有であるため）。 | 効率的 (クライアント接続はデータベースに固有であるため）。 | ある程度効率的。(使用する ORM、ユーザー/ロールのセキュリティモデル、search\$1path設定によっては、クライアントがすべてのテナントのメタデータをキャッシュし、DB 接続メモリ使用率が高くなることがあります）。 | 効率的 (すべてのテナントが同じテーブルを共有するため）。 | 
| 統合されたテナントレポート作業 | 多大な労力。(外部データラッパー [FDWs を使用して、すべてのテナントのデータを統合するか、[ETL] を別のレポートデータベースに抽出、変換、ロードする必要があります）。 | 多大な労力。(FDWs を使用して、すべてのテナントまたは ETL のデータを別のレポートデータベースに統合する必要があります）。 | 中程度の労力。(ユニオンを使用して、すべてのスキーマにデータを集約できます）。 | 最小限の労力。(すべてのテナントデータは同じテーブルにあるため、レポートは簡単です）。 | 
| レポート用のテナント固有の読み取り専用インスタンス (サブスクリプションに基づくなど) | 最小労力。(リードレプリカを作成します。) | 中程度の労力。(論理レプリケーションまたは AWS Database Migration Service [AWS DMS] を使用して設定できます。) | 中程度の労力。(論理レプリケーションまたは を使用して AWS DMS 設定できます）。 | 複雑 (すべてのテナントが同じテーブルを共有するため）。 | 
| データ分離 | 最適です。 | より良い。(PostgreSQL ロールを使用してデータベースレベルのアクセス許可を管理できます）。 | より良い。(PostgreSQL ロールを使用してスキーマレベルのアクセス許可を管理できます）。 | 悪化。(すべてのテナントが同じテーブルを共有するため、テナント分離のために行レベルのセキュリティ [RLS] などの機能を実装する必要があります）。 | 
| テナント固有のストレージ暗号化キー | 可能。(各 PostgreSQL クラスターは、ストレージ暗号化用に独自の AWS Key Management Service [AWS KMS] キーを持つことができます）。 | できません。(すべてのテナントはストレージ暗号化のために同じ KMS キーを共有します）。 | できません。(すべてのテナントはストレージ暗号化のために同じ KMS キーを共有します）。 | できません。(すべてのテナントはストレージ暗号化のために同じ KMS キーを共有します）。 | 
| 各テナントのデータベース認証に AWS Identity and Access Management (IAM) を使用する | 可能。 | 可能。 | 可能 (スキーマごとに個別の PostgreSQL ユーザーを持つ）。 | できません (テーブルはすべてのテナントによって共有されるため）。 | 
| インフラストラクチャコスト | 最高 (何も共有されないため）。 | 中程度。 | 中程度。 | 最小。 | 
| データ重複とストレージの使用 | すべてのテナントで最も高い集計。(PostgreSQL システムカタログテーブルとアプリケーションの静的データと共通データはすべてのテナントに複製されます）。 | すべてのテナントで最も高い集計。(PostgreSQL システムカタログテーブルとアプリケーションの静的データと共通データはすべてのテナントに複製されます）。 | 中程度。(アプリケーションの静的データと共通データは、共通のスキーマにあり、他のテナントからアクセスできます）。 | 最小。(データの重複はありません。 アプリケーションの静的データと共通データは、同じスキーマ内に存在できます）。 | 
| テナント中心のモニタリング (どのテナントが問題を引き起こしているかをすばやく調べる) | 最小労力。(各テナントは個別にモニタリングされるため、特定のテナントのアクティビティを簡単に確認できます）。 | 中程度の労力。(すべてのテナントが同じ物理リソースを共有するため、特定のテナントのアクティビティをチェックするために追加のフィルタリングを適用する必要があります）。 | 中程度の労力。(すべてのテナントが同じ物理リソースを共有するため、特定のテナントのアクティビティをチェックするために追加のフィルタリングを適用する必要があります）。 | 多大な労力。(すべてのテナントはテーブルを含むすべてのリソースを共有するため、バインド変数キャプチャを使用して、特定の SQL クエリが属するテナントを確認する必要があります）。 | 
| 一元管理とヘルス/アクティビティモニタリング | 多大な労力 (中央モニタリングと中央コマンドセンターをセットアップするため）。 | 中程度の労力 (すべてのテナントが同じインスタンスを共有するため）。 | 中程度の労力 (すべてのテナントが同じインスタンスを共有するため）。 | 最小限の労力 (スキーマを含むすべてのテナントが同じリソースを共有するため）。 | 
| オブジェクト識別子 (OID) とトランザクション ID (XID) の循環の可能性 | 最小。 | 高 (OID のため、XID は単一の PostgreSQL クラスター全体のカウンターであり、物理データベース間で効果的にバキューム処理を行うことに問題がある可能性があります）。 | 中程度。(OID のため、XID は単一の PostgreSQL クラスター全体のカウンターです）。 | 高 (例えば、1 つのテーブルが TOAST OID 制限の 40 億に達すると、out-of-line列の数に応じてます）。 | 