適用対象: Azure Database for PostgreSQL - フレキシブル サーバー
Azure Database for PostgreSQL フレキシブル サーバー上のエラスティック クラスターは、PostgreSQL へのオープンソースの Citus 拡張機能のマネージド オファリングであり、PostgreSQL の水平シャーディングを可能にします。
Citus は単なる拡張機能ですが、複数の PostgreSQL インスタンスを接続します。 Azure Database for PostgreSQL フレキシブル サーバーを Citus と共にデプロイすると、複数の PostgreSQL インスタンスの管理と構成が単一のリソースとして処理されます。 また、ノードを自動的に設定し、Citus 拡張機能で認識されるようにします。
フレキシブル サーバー上のエラスティック クラスターには、行ベースのシャーディングとスキーマベースのシャーディングの 2 つのシャーディング モデルが用意されています。 詳細については、シャーディング モデルに関するオープンソースのドキュメントを参照してください。
Architecture
エラスティック クラスターは、Azure Database for PostgreSQL フレキシブル サーバーの 1 つ以上のノードで構成されます。 これらのインスタンスは自動的に相互に認識され、相互接続されて Citus クラスターを形成します。 ノードは、同じコンピューティング層とストレージ層のものである必要があり、均一に、上位層にスケールアップするか、下位層にスケールダウンすることができます。
エラスティック クラスターは、フレキシブル サーバーのインスタンス (ノードと呼ばれます) を使用して、"共有なし" アーキテクチャ内で相互に調整します。 クラスター内のノードは、単一サーバーの場合より多くのデータを集合的に保持し、より多くの CPU コアを使用します。 このアーキテクチャでは、クラスターにノードを追加してデータベースを拡張することもできます。
ポート 5432 を使用してクラスターに接続すると、指定されたコーディネーター ノードに接続されます。 また、エラスティック クラスターを使用すると、ポート 7432 を使用して接続している場合、5 タプル ハッシュ方式を使用してクラスター全体で接続を負荷分散できます。 7432 を使用しても、現在コーディネーターとして指定されているノードに接続できます。 テーブルの分散など、クラスター全体の特定の操作では、ポート 5432 経由で接続する必要がある場合があります。 アプリケーション スキーマのアップグレードや同様の変更を行う場合は、常にポート 5432 で接続することを強くお勧めします。
Cosmos DB for PostgreSQL とは異なり、ノード アドレスは外部に公開されません。 pg_dist_node
のような Citus メタデータ テーブルを見ると、すべてのノードが同じ IP アドレス (例では 10.7.0.254
) を持ちながら、ポート番号は異なることに気付くかもしれません。
select nodeid, nodename, nodeport from pg_dist_node;
nodeid | nodename | nodeport
--------+------------+----------
1 | 10.7.0.254 | 7000
2 | 10.7.0.254 | 7001
(2 rows)
これらのノードは同じマシン上の異なるポートのように見える場合でも、Azure のインフラストラクチャでは、異なる仮想マシン上に存在します。
Citus の詳細については、公式のオープンソース プロジェクト ドキュメントを参照してください。
既定では、Citus で作成されたテーブルとスキーマはクラスター間で自動的に分散されません。 シャーディング モデルを決定し、スキーマを分散するか、行ベースのシャーディングを使用してテーブル データを分散するかを決定する必要があります。
分散テーブルに対するクエリごとに、クエリ対象のノードはそれを単一のノードにルーティングするか、複数のノード間で並列処理します。 その判断は、必要なデータが単一のノードに存在するか、複数のノードに存在するかによって決まります。 スキーマベースのシャーディングでは、コーディネーターはスキーマをホストするノードにクエリを直接ルーティングします。 スキーマベースのシャーディングと行ベースのシャーディングのどちらでも、ノードはメタデータ テーブルを参照して何を行うかを決定します。 これらのテーブルは、ノードの場所と正常性、およびノード間でのデータの分散を追跡します。
いずれかのシャーディング モデルを使用してデータが分散されると、任意のノードに接続して DML (データ変更言語) 操作 (SELECT、UPDATE、INSERT、DELETE) を実行できます。 すべてのノードには、クエリに必要なデータを検索するために必要なメタデータが含まれており、それを取得してクエリに応答することができます。
現時点では、DDL (データ定義言語) 操作とクラスター全体の操作は、コーディネーター ロールを保持するノードに制限されています。 DDL およびクラスター全体の操作は、ポート 7432 を使用する代わりにポート 5432 に接続して実行してください。
エラスティック クラスターをスケールアウトするには、新しいノードを追加し、エラスティック クラスター上のデータを再調整します。 再調整はオンライン操作であり、実行中のワークロードはブロックされません。
シャード
前のセクションでは、分散テーブルがワーカー ノード上にシャードとしてどのように格納されるかについて説明しました。 このセクションでは、これらのシャードに関するさらに技術的な詳細について説明します。
pg_dist_shard
メタデータ テーブルには、システム内の各分散テーブルの各シャードの行が含まれます。 行は、ハッシュ領域 (shardminvalue
、shardmaxvalue
) 内の整数の範囲でシャード識別子 (shardid
) に一致します。
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
と呼ばれるテーブルで読み取られるか書き込まれます。 拡張機能は、メタデータ テーブルに保存されている情報を使用して、特定の worker が何であるかを判断します。 シャードからワーカーへのマッピングは、シャード配置と呼ばれます。
ノードでは、github_events_102027
のような特定のテーブルを参照するフラグメントにクエリが再書き込みされ、これらのフラグメントが適切なワーカー上で実行されます。 識別子 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 │
└─────────┴───────────┴──────────┘