EDB Postgres Distributed Proxy overview#

特に非同期レプリケーションでは、競合を回避し、アプリケーションの可用性を保証するために、一貫した書き込みリーダーノードを持つことが重要です。

EDB Postgres Distributedのプロキシレイヤーの2つの部分は次のとおりです。

  • プロキシ構成とルーティング情報。 PGDコンセンサスメカニズムによって維持されます。

  • ホストにインストールされるPGDプロキシサービス。 PGDクラスターに接続し、構成を読み取り、ルーティング情報の変更をリッスンします。

これは、通常、高可用性構成PGDグループごとにプロキシサービスの少なくとも2つのインスタンスでインストールされます。

構成が完了すると、 PGDプロキシサービスは、 EDB Postgres分散クラスターによって決定されたとおりにルーティングの変更を監視します。これらの変更に基づいて動作して、接続が一貫して正しいノードにルーティングされるようにします。

PGDプロキシサービスの構成変更は、 PGDクラスターを介して行われます。 PGDプロキシサービスは、PGDクラスターから構成を読み取りますが、プロキシサービスを再起動してこれらの変更を適用する必要があります。

現在選択されている書き込みノードおよび読み取りノードに関する情報は、bdr.node_group_routing_summary に表示されます。これはノードローカルビューです。プロキシは常にRaftリーダーから読み取り、最新の一貫したビューを取得します。

リーダーの選択#

書き込みリーダーは、現在のRaftリーダーによって選択されますサブグループ1またはトップレベルグループ1、サブグループのリーダーまたはクラスターのトップレベルグループが選択されているかどうかに応じて。

リーダーは、

PGDプロキシクラスター構成 で説明している構成に基づいて、到達可能で基準を満たす候補ノードから選択されます。実行可能な候補になるには、ノードでroute_writes

が有効になりroute_fence が無効で、以前のリーダーからroute_writer_max_lag 有効な場合内にある必要があります。候補者はroute_priority で降順に、以前のリーダーからの遅延で昇順に並べられます。

新しいリーダー選択プロセスは、現在既存のリーダーが存在しない場合に開始されます。これは、有効な候補がなかったか、Raftがダウンしていたためである可能性があります。既存のリーダーへの接続が失われた場合。

ノードは、リーダーから受け取った最後のRaftプロトコルメッセージがRaft選挙タイムアウトより古くない場合、接続されているとみなされます

内部設定-Raftタイムアウト bdr.raft_global_election_timeout を参照してください。

Raftリーダーは選択タイムアウト制限ごとに3回ハートビートを送信しているため、リーダーノードは、切断されたと考えられる前に3つのハートビートへの応答を逃す必要があります。

PGDプロキシクラスター構成#

PGDクラスターには、常に少なくとも1つのトップレベルグループと1つのデータグループがあります。 PGDは、 enable_proxy_routing およびenable_raft オプションがtrueに設定されている各データグループの書き込みリーダーを選択します。

クラスターは、各グループのプロキシ構成も維持します。各構成には名前があり、グループに関連付けられています。プロキシは、トップレベルのグループまたはデータグループにアタッチできます。各グループに複数のプロキシをアタッチできます。

PGDプロキシサービスがホストで実行を開始すると、ローカル構成ファイルに名前があり、グループ内のノードに接続します。そこから、名前を使用して、グループに保存されている完全な構成を検索します。

PGDプロキシサービス#

EDB Postgres分散プロキシPGDプロキシサービスは、クライアントアプリケーションとPostgres間の抽象化レイヤーとして機能するプロセスです。 PGDコンセンサスメカニズムとインターフェイスして、現在の書き込みリーダーノードのIDを取得し、トラフィックをそのノードにリダイレクトします。また、オプションで読み取り専用モードをサポートし、書き込みリーダーではないノードに読み取り専用クエリをルーティングできるため、クラスターの全体的なパフォーマンスを向上させます。

PGDプロキシは、TCPレイヤー4プロキシです。

連携する方法#

PGDプロキシは、起動時に、ローカル構成ファイルで指定されたエンドポイントのいずれかに接続します。それは取得します

  • 全ノードのDB接続情報

  • リッスンアドレス、リッスンポートなどのプロキシオプション

  • デフォルトモードの現在の書き込みリーダー、読み取り専用モードの読み取りノード、または任意のモードの両方を含むルーティングの詳細。

構成ファイルで指定されたエンドポイントは、起動時にのみ使用されます。その後、実際のエンドポイントは、 PGDカタログの bdr.node_routing_config_summary のroute_dsn フィールドから取得されます。

PGDは、書き込みリーダー選択を管理します。 PGDプロキシはPGDと対話して、Postgres通知/リッスンチャネルで書き込みリーダー変更イベント通知を取得し、クライアントトラフィックを現在の書き込みリーダーにルーティングします。 PGDプロキシは、書き込みリーダーの変更または書き込みリーダーが使用できないときに、既存のすべてのクライアント接続を切断します。書き込みリーダー選挙はRaftによってサポートされるアクティビティであり、Raftリーダーの可用性の対象となります。書き込みリーダーが使用できない場合、 PGDプロキシは新しいクライアント接続を閉じます。

PGDプロキシは、 フェールオーバー と スイッチオーバー の2つの操作モードに分類できる書き込みリーダー変更イベントに応答します。

Postgresまたはオペレーティングシステムがクラッシュした場合に、現在の書き込みリーダーノードから新しいノードへの書き込みリーダーシップの自動転送は、 フェールオーバー と呼ばれます。 PGDは、現在の書き込みリーダーがダウンするか、応答しなくなると、新しい書き込みリーダーを選択します。新しい書き込みリーダーがPGDによって選択されると、 PGDプロキシは古い書き込みリーダーへの既存のクライアント接続を閉じ、新しいクライアント接続を新しく選択された書き込みリーダーにリダイレクトします。

現在の書き込みリーダーから新しいターゲットリーダーへのユーザー制御の手動転送は、 スイッチオーバー と呼ばれます。スイッチオーバーは、

PGD CLI switchover コマンドを介してトリガーされます。コマンドはPGDに送信され、指定されたターゲットノードを新しい書き込みリーダーとして選択しようとします。フェールオーバーと同様に、

PGDプロキシは既存のクライアント接続を閉じ、新しいクライアント接続を新しく選択された書き込みリーダーにリダイレクトします。これは、サーバーのメンテナンス中に、たとえば、サーバーの更新やOSパッチの更新などのメンテナンスのために現在の書き込みリーダーノードを停止する必要がある場合に役立ちます。

プロキシが読み取り専用ルーティングをサポートするように構成されている場合、読み取り専用クエリを書き込みリーダーではないノードのプールにルーティングできます。ノードのプールはPGDクラスターによって維持され、プロキシはプールへの変更をリッスンします。プールが変更されると、プロキシはルーティング構成を更新し、ノードの新しいプールへの読み取り専用クエリのルーティングを開始し、プールを離れたノードへの既存のクライアント接続の切断を開始します。

コンセンサス猶予期間#

PGDプロキシは、Raftリーダーの損失時にルーティング動作を構成するために使用できるconsensus_grace_period プロキシオプションを提供します。 PGDプロキシは、この期間にわたって現在の書き込みリーダー利用可能な場合にルーティングし続けます。この期間中に新しいRaftリーダーが選出されない場合、プロキシはルーティングを停止します。 0s に設定されている場合、PGDプロキシはルーティングをすぐに停止します。

このオプションの主な目的は、Raftリーダーが失われたときにユーザーが書き込み動作を構成できるようにすることです。 Raftリーダーがクラスターに存在しない場合、プロキシから見られる現在の書き込みリーダーが正しいものであるとは、必ずしも保証されません。場合によっては、次の例のネットワークパーティションのように、2つの書き込みリーダーが、同じグループに接続された2つの異なるプロキシによって認識され、書き込み競合の可能性が増加する可能性があります。これが目的の動作でない場合は、前述のconsensus_grace_period を0sに設定できます。この設定は、Raftリーダーが失われたことを検出すると、ルーティングを停止し、既存のオープン接続をすぐに閉じるようにプロキシを構成します。

ネットワークパーティションの例#

各データノードにプロキシがある3つのデータノードグループを検討します。この場合、現在の書き込みリーダーがネットワーク分割または分離されると、マジョリティパーティションに存在するデータノードが新しい書き込みリーダーを選択します。 consensus_grace_period がゼロ以外の値10s に設定されている場合、以前の書き込みリーダーに存在するプロキシは、この期間書き込みをルーティングし続けます。

この場合、猶予期間が長すぎると、2つの書き込みリーダーで書き込みが発生し続けます。この条件により、書き込み競合が発生する可能性が増加します。

そうは言っても、ほとんどの場合、現在のRaftリーダーを失うと、ノードクォーラムの半分以上がまだ残っている場合、新しいRaftリーダーは数秒以内にBDRによって選択されます。したがって、Raftリーダーがダウンしているが、書き込みリーダーがまだアップしている場合、consensus_grace_period をゼロ以外の正の値に保つことにより、ルーティングを許可するようにプロキシを構成できます。プロキシは、ルーティングを停止する前に、この期間にRaftリーダーが選出されるのを待ちます。これは、可用性がより重要な場合に役立つ場合があります。

コンセンサス読み取り猶予期間#

consensus_grace_period と同様に、 read_consensus_grace_period オプションは読み取り専用ルーティングで使用できます。このオプションは、読み取り専用クエリのRaftリーダーが損失した際のルーティング動作を構成するために使用できます。 PGDプロキシは、この期間中、現在の読み取りノードへのルーティングを継続します。この期間中に新しいRaftリーダーが選出されない場合、プロキシは読み取り専用クエリのルーティングを停止します。 0s に設定されている場合、PGDプロキシは読み取り専用クエリのルーティングをすぐに停止します。

マルチホスト接続文字列#

PostgreSQL Cクライアントライブラリlibpqを使用すると、単純なフェイルオーバーのために単一の接続文字列で複数のホスト名を指定できます。これは、他の一部のプログラミング言語のクライアントライブラリドライバーでもサポートされています。ダウンまたはアクセス不能なPGDプロキシインスタンス全体のフェイルオーバーに適しています。

ただし、 PGDプロキシインスタンスにアクセスできるが、書き込みリーダーにアクセスできない場合、または特定のインスタンスの書き込みリーダーが存在しない場合、つまり、特定のPGDグループに書き込みリーダーがないため、接続単に失敗するだけです。マルチホスト接続文字列内の他のホストは試行されません。この動作は、 HAProxyやpgbouncerなどの他のプロキシを使用したPostgreSQLクライアントライブラリの動作と一貫しています。