EDB Postgres Distributed Proxy

EDB Postgres分散プロキシは、クライアントアプリケーションとPostgres間の抽象化レイヤーとして機能するデーモンです。 PGDコンセンサスメカニズムとインターフェイスして、現在の書き込みリーダーノードのIDを取得し、トラフィックをそのノードにリダイレクトします。

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

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

仕組み

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

・全ノードのDB接続情報

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

  • 現在の書き込みリーダーなどのルーティングの詳細

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

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

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

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

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

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

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

コンセンサス猶予期間

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

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

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

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

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

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

マルチホスト接続文字列

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

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

PGDプロキシの管理

PGD CLIには、 create-proxy 、 delete-proxy 、 set-proxy-options 、 show-proxies など、PGDクラスター内のプロキシを管理するためのいくつかのコマンドが用意されています。詳細については、 PGD CLIの使用 を参照してください。

PGDプロキシの構成と管理のPGD側の詳細については、

接続管理 を参照してください。

プロキシヘルスチェック

PGDプロキシは、次のHTTP(s)ヘルスチェックAPIエンドポイントを提供します。 APIエンドポイントは、 GET リクエストに応答します。使用する前に有効にして構成する必要があります。これを行う方法については、 競合ログ構成のリスト を参照してください。

GET /health/is-ready
GET /health/is-live

準備

プロキシは、有効な「GET」リクエストを受信すると、現在の書き込みリーダーに接続を正常にルーティングできるかどうかを確認します。チェックが正常に終了した場合、APIはtrue を含む本文とHTTPステータスコード200 (OK) で応答します。それ以外の場合、HTTPステータスコード500 (Internal Server Error) とともにfalse を含む本文を返します。

活気

ライブネスチェックは、HTTPステータスコード200 (OK) またはエラーでtrue を返しますが、false は返しません。これは、プロキシサービスの開始または終了に失敗すると、要求をリッスンしているHTTPサーバーが自動的に停止するためです。

プロキシログの場所

syslog

  • Debianベース- /var/log/syslog

  • Red Hatベース- /var/log/messages

journalctl コマンドを使用して、プロキシのトラブルシューティング用にログをフィルタリングおよび表示します。以下は、クイックリファレンスのためのいくつかのサンプルコマンドです。

journalctl -u pgd-proxy -n100 -f
journalctl -u pgd-proxy --since today
journalctl -u pgd-proxy --since "10 min ago"
journalctl -u pgd-proxy --since "2022-10-20 16:21:50" --until "2022-10-20 16:21:55"