Azure Database for PostgreSQL フレキシブル サーバーのエラスティック クラスター

Azure Database for PostgreSQL サービス上のエラスティック クラスターは、PostgreSQL の水平シャーディングを可能にする PostgreSQL に対するオープンソース Citus 拡張機能のマネージド オファリングです。

Citus は単なる拡張機能ですが、複数の PostgreSQL インスタンスを接続します。 Citus を使用してAzure Database for PostgreSQLフレキシブル サーバーをデプロイすると、複数の PostgreSQL インスタンスの管理と構成が 1 つのリソースとして処理されます。 また、ノードを自動的に設定し、Citus 拡張機能で認識されるようにします。

サービス上のエラスティック クラスターには、行ベースのシャーディングとスキーマベースのシャーディングという 2 つのシャーディング モデルが用意されています。 詳細については、 シャーディング モデルに関するオープン ソースのドキュメントを参照してください。

Architecture

エラスティック クラスターは、Azure Database for PostgreSQL フレキシブル サーバーの 1 つ以上のノードで構成されます。 これらのインスタンスは自動的に互いを検出し、相互接続して Citus クラスターを形成します。 ノードは同じコンピューティング層とストレージ層である必要があり、それらを上位レベルまたは下位レベルに均一にスケールアップまたはスケールダウンできます。

エラスティック クラスターでは、フレキシブル サーバー (ノードと呼ばれる) のインスタンスを使用して、"共有なし" アーキテクチャで相互に調整します。 このアーキテクチャでは、クラスターにノードを追加してデータベースを拡張することもできます。

エラスティック クラスターでは、フレキシブル サーバー (ノードと呼ばれます) を使用して、 共有無 しアーキテクチャで相互に調整します。 このアーキテクチャでは、クラスターにノードを追加してデータベースを拡張することもできます。

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 メタデータ テーブルには、システム内の各分散テーブルの各シャードの行が含まれます。 行は、ハッシュ領域 (shardidshardminvalue) 内の整数の範囲でシャード識別子 (shardmaxvalue) に一致します。

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 │
└─────────┴───────────┴──────────┘