Important
Azure Cosmos DB for PostgreSQL は提供終了パスにあり、新しいプロジェクトでは推奨されなくなりました。 代わりに、次の 2 つのサービスのいずれかを使用します。
PostgreSQL ワークロードの場合: Azure Database For PostgreSQL のエラスティック クラスター機能を使用して、オープンソースの Citus 拡張機能に含まれる水平スケールアウトおよび分散 PostgreSQL 機能を使用します。
NoSQL ワークロードの場合は、99.999% 可用性サービス レベル アグリーメント (SLA)、インスタント 自動スケール、および複数のリージョン間の自動フェールオーバーを含む分散データベース ソリューションに対して Azure Cosmos DB for NoSQL を使用します。
ノード
Azure Cosmos DB for PostgreSQL を使用すると、PostgreSQL サーバー (ノードと呼ばれる) は "シェアード ナッシング方式" のアーキテクチャで互いに調和できるようになります。 クラスター内のノードは、単一サーバーの場合より多くのデータを集合的に保持し、より多くの CPU コアを使用します。 このアーキテクチャでは、クラスターにノードを追加してデータベースを拡張することもできます。
コーディネーターとワーカー
各クラスターに、1 つのコーディネーター ノードと複数のワーカーが存在します。 アプリケーションは、クエリをコーディネーター ノードに送信し、このノードが関連するワーカーにリレーして、結果を累積します。
Azure Cosmos DB for PostgreSQL を使用すると、データベース管理者は、異なる行を異なるワーカー ノード上に格納してテーブルやスキーマを分散することができます。 分散したテーブルやスキーマは、Azure Cosmos DB for PostgreSQL のパフォーマンスにとって重要です。 テーブルやスキーマを分散しないと、それらはコーディネーター ノード上に完全に残り、マシン間の並列処理を利用できません。
分散テーブル上の各クエリに対して、コーディネーターは、必要なデータが単一または複数のノードのどちらに存在するかに応じて、単一のワーカー ノードにルーティングするか、または複数にわたって並列処理を行います。 スキーマベースのシャーディングでは、スキーマをホストするノードにコーディネーターがクエリを直接ルーティングします。 スキーマベースのシャーディングと行ベースのシャーディングのどちらにおいても、コーディネーターはメタデータ テーブルを参照して、何を行うかを決定します。 これらのテーブルは、ワーカー ノードの DNS 名およびヘルスと、ノード間でのデータの分布を追跡します。
テーブル型
クラスターには 5 つのテーブル型があり、それぞれが、ノードでは異なる方法で格納され、異なる目的に使用されます。
型 1:分散テーブル
最もよく使用される最初の型が分散テーブルです。 SQL ステートメントには通常のテーブルのように見えますが、ワーカー ノードにわたり水平方向にパーティション分割されます。 この意味は、テーブルの各行が異なるノードの、シャードと呼ばれるフラグメント テーブルに格納されるということです。
Azure Cosmos DB for PostgreSQL では、クラスター全体で SQL ステートメントだけではなく DDL ステートメントも実行されます。 分散テーブルのスキーマの変更は、ワーカーにわたるすべてのテーブルのシャードの更新にカスケーディングされます。
ディストリビューション列
Azure Cosmos DB for PostgreSQL では、アルゴリズムのシャーディングを使用して行がシャードに割り当てられます。 割り当ては、ディストリビューション列と呼ばれるテーブル列の値に基づいて決定論的に行われます。 クラスター管理者は、テーブルを配布するときに、この列を指定する必要があります。 パフォーマンスおよび機能には、適切な選択を行うことが重要です。
型 2:参照テーブル
参照テーブルは、コンテンツ全体が単一のシャードに集中される一種の分散テーブルです。 シャードは、すべてのワーカーにレプリケートされます。 いずれかのワーカーに対するクエリは、参照情報にローカルでアクセスでき、別のノードから行を要求するネットワーク オーバーヘッドは生じません。 行ごとに個別のシャードを区別する必要がないため、参照テーブルにはディストリビューション列はありません。
参照テーブルは通常小さく、任意のワーカー ノードで実行されるクエリに関連したデータの格納に使用されます。 たとえば、注文ステータスや製品カテゴリなどの列挙値があります。
型 3:ローカル テーブル
Azure Cosmos DB for PostgreSQL を使用する場合、接続先のコーディネーター ノードは通常の PostgreSQL データベースです。 コーディネーター上に通常のテーブルを作成し、それらをシャードしないように選択できます。
ローカル テーブルの適切な候補は、結合クエリに参加していない小規模の管理用テーブルになります。 これにはたとえば、アプリケーションのサインインと認証に使用される users テーブルがあります。
4 型: ローカル マネージド テーブル
ローカル テーブルと参照テーブルの間に外部キー参照が存在する場合、Azure Cosmos DB for PostgreSQL はローカル テーブルをメタデータに自動的に追加する場合があります。 さらに、通常のローカル テーブルに対して create_reference_table citus_add_local_table_to_metadata 関数を実行して、ローカルで管理するテーブルを手動で作成できます。 メタデータに存在するテーブルは管理テーブルと見なされ、任意のノードからクエリを実行できます。Citus は、ローカル管理テーブルからデータを取得するためにコーディネーターにルーティングすることを認識しています。 このようなテーブルは、citus_tables ビューにローカルとして表示されます。
5 型: スキーマ テーブル
Citus 12.0 で導入されたスキーマベースのシャーディングでは、分散スキーマが個々のコロケーション グループに自動的に関連付けられます。 これらのスキーマ内で作成されたテーブルは、シャード キーなしで、コロケーションされた分散テーブルに自動的に変換されます。 このようなテーブルはスキーマ テーブルと見なされ、citus_tables ビューにスキーマとして表示されます。
シャード
前のセクションでは、分散テーブルがワーカー ノード上にシャードとしてどのように格納されるかについて説明しました。 このセクションでは、さらに技術的な詳細について説明します。
コーディネーター上の pg_dist_shard メタデータ テーブルには、システム内の分散テーブルの各シャードの行が含まれます。 行は、ハッシュ領域 (shardminvalue、shardmaxvalue) 内の整数の範囲でシャード ID に一致します。
SELECT * from pg_dist_shard;
logicalrelid | shardid | shardstorage | shardminvalue | shardmaxvalue
---------------+---------+--------------+---------------+---------------
github_events | 102026 | t | 268435456 | 402653183
github_events | 102027 | t | 402653184 | 536870911
github_events | 102028 | t | 536870912 | 671088639
github_events | 102029 | t | 671088640 | 805306367
(4 rows)
コーディネーター ノードでは、どのシャードが github_events の行を保持するかを判断する場合、行のディストリビューション列の値がハッシュされます。 その後、ノードにより、どのシャードの範囲にハッシュされた値が含まれるか調べられます。 範囲は、ハッシュ関数のイメージが disjoint 結合になるように定義されます。
シャードの配置
シャード 102027 が問題の行に関連付けられているとします。 行は、いずれかのワーカーにおいて、github_events_102027 と呼ばれるテーブルで読み取られるか書き込まれます。 どのワーカーでしょうか。 これは、すべてメタデータ テーブルによって決定されます。 シャードからワーカーへのマッピングは、シャード配置と呼ばれます。
コーディネーター ノードでは、github_events_102027 のような特定のテーブルを参照するフラグメントにクエリが再書き込みされ、これらのフラグメントが適切なワーカー上で実行されます。 シャード ID 102027 を保持しているノードを見つけるためにバックグラウンドで実行されるクエリの例を次に示します。
SELECT
shardid,
node.nodename,
node.nodeport
FROM pg_dist_placement placement
JOIN pg_dist_node node
ON placement.groupid = node.groupid
AND node.noderole = 'primary'::noderole
WHERE shardid = 102027;
┌─────────┬───────────┬──────────┐
│ shardid │ nodename │ nodeport │
├─────────┼───────────┼──────────┤
│ 102027 │ localhost │ 5433 │
└─────────┴───────────┴──────────┘
次のステップ
- アプリケーションの種類を特定してデータ モデリングの準備をする
- 便利な診断クエリを使用してシャードと配置を検査します。