レプリケーションモード

PatroniはPostgreSQLストリーミングレプリケーションを使用しています。ストリーミングレプリケーションの詳細については、 Postgres documentation _を参照してください。デフォルトでは、PatroniはPostgreSQLを非同期レプリケーション用に構成します。レプリケーションスキーマの選択は、ビジネス上の考慮事項によって異なります。非同期レプリケーションと同期レプリケーションの両方、および他のHAソリューションを調査して、どのソリューションが最適かを判断します。

非同期モードの持続性

非同期モードでは、可用性を確保するために、クラスターはコミットされたトランザクションの一部を失うことが許可されます。プライマリサーバーに障害が発生したり、他の理由で使用できなくなった場合、Patroniは自動的に十分に健全なスタンバイをプライマリに昇格させます。そのスタンバイにレプリケートされていないトランザクションは、プライマリの/「フォークされたタイムライン/」に残り、実質的に回復不能です[1]_。

失われる可能性のあるトランザクションの量は、 maximum_lag_on_failover パラメーターで制御されます。プライマリトランザクションログの位置はリアルタイムでサンプリングされないため、実際にはフェイルオーバーで失われるデータの量は、トランザクションログの maximum_lag_on_failover バイトと最後の ttl 秒( loop_wait /2秒に書き込まれた量によって制限される最悪の場合です平均的な場合)。ただし、一般的な定常状態のレプリケーション遅延は1秒未満です。

デフォルトでは、リーダー選挙を実行するときに、Patroniはレプリカの現在のタイムラインを考慮しません。これは、場合によっては望ましくない動作になる可能性があります。 check_timeline パラメーターの値を true 変更することにより、元のプライマリが新しいリーダーになるのと同じタイムラインを持たないノードを防ぐことができます。

PostgreSQL同期レプリケーション

PatroniでPostgresの synchronous replication _を使用できます。同期レプリケーションは、接続しているクライアントに成功して戻る前に、書き込みがセカンダリに書き込まれることを確認することにより、クラスター全体の一貫性を保証します。同期レプリケーションのコスト:書き込みのスループットが低下します。このスループットは、完全にネットワークパフォーマンスに基づいています。

ホストされたデータセンター環境(AWS、Rackspace、または制御できないネットワークなど)では、同期レプリケーションにより書き込みパフォーマンスの変動が大幅に増加します。フォロワーがリーダーからアクセスできなくなると、リーダーは効果的に読み取り専用になります。

単純な同期レプリケーションテストを有効にするには、YAML構成ファイルの parameters セクションに次の行を追加します。

synchronous_commit: "on"
synchronous_standby_names: "*"

PostgreSQL同期レプリケーションを使用する場合は、少なくとも3つのPostgresデータノードを使用して、1つのホストに障害が発生した場合の書き込み可用性を保証します。

PostgreSQL同期レプリケーションを使用しても、あらゆる状況下でトランザクションの損失がゼロになることは保証されません。プライマリと、現在同期レプリカとして機能しているセカンダリに同時に障害が発生すると、すべてのトランザクションが含まれていない可能性のある3番目のノードが昇格されます。

同期モード

コミットされたトランザクションを失うことが許可されないユースケースでは、Patroniの synchronous_mode をオンにすることができます。 synchronous_mode がオンになると、Patroniはスタンバイに成功したコミットステータスをクライアントに返した可能性のあるすべてのトランザクションが含まれていることが確実でない限り、スタンバイをプロモートしません[2]_。これは、一部のサーバーが利用可能であっても、システムが書き込みに利用できない可能性があることを意味します。システム管理者は、トランザクションが失われた場合でも、手動フェールオーバーコマンドを使用してスタンバイを昇格できます。

synchronous_mode をオンにしても、あらゆる状況下でのコミットのマルチノード耐久性が保証されるわけではありません。適切なスタンバイが利用できない場合、プライマリサーバーは引き続き書き込みを受け入れますが、レプリケーションは保証しません。このモードでプライマリに障害が発生すると、スタンバイはプロモートされません。システム管理者が手動フェールオーバーを実行しない限り、以前プライマリだったホストが戻ってくると、自動的に昇格します。この動作により、2ノードクラスターで同期モードを使用できるようになります。

synchronous_mode がオンで、スタンバイがクラッシュすると、パトローニの次の反復が実行され、プライマリがスタンドアロンモードに切り替えるまでコミットはブロックされます(書き込みの最悪の場合の遅延 ttl 秒、平均の場合 loop_wait /2秒)。スタンバイを手動でシャットダウンまたは再起動しても、コミットサービスは中断されません。スタンバイは、PostgreSQLのシャットダウンが開始される前に、プライマリに同期スタンバイ義務から自分自身を解放するように通知します。

各書き込みが少なくとも2つのノードに永続的に保存されることを保証する必要がある場合は、 synchronous_mode に加えて synchronous_mode_strict を有効にします。このパラメーターは、利用可能な同期スタンバイ候補がない場合にPatroniがプライマリで同期レプリケーションをオフに切り替えないようにします。マイナス面として、プライマリは書き込みに利用できず(Postgresトランザクションが明示的に synchronous_mode をオフにしない限り)、少なくとも1つの同期レプリカが起動するまですべてのクライアントの書き込み要求をブロックします。

nosync タグをtrueに設定することで、スタンバイが同期スタンバイにならないようにすることができます。これは、低速のネットワーク接続の背後にあり、同期スタンバイになったときにパフォーマンスの低下の原因となるスタンバイに設定することをお勧めします。

同期モードは、PatroniRESTインターフェイスを介してオン/オフを切り替えることができます。手順については、 dynamic configuration を参照してください。

注:PostgreSQLでの同期レプリケーションの実装方法により、 synchronous_mode_strict を使用していてもトランザクションを失う可能性があります。レプリケーションの確認を待っている間にPostgreSQLバックエンドがキャンセルされた場合(クライアントのタイムアウトまたはバックエンドの障害によるパケットキャンセルの結果)、トランザクションの変更は他のバックエンドで可視になります。このような変更はまだレプリケートされておらず、スタンバイプロモーションの場合に失われる可能性があります。

同期レプリケーション係数

パラメーター synchronous_node_count は、Patroniによって使用され、同期スタンバイデータベースの数を管理します。デフォルトでは1に設定されています。 synchronous_mode がoffに設定されている場合、効果はありません。有効にすると、Patroniはパラメーター synchronous_node_count に基づいて正確な数の同期スタンバイデータベースを管理し、メンバーが参加および離脱するときにDCSおよびsynchronous_standby_namesの状態を調整します。

同期モードの実装

同期モードの場合、PatroniはDCSで同期状態を維持し、最新のプライマリおよび現在の同期スタンバイデータベースを含みます。この状態は、次の不変条件を保証するために、厳密な順序付け制約で更新されます。

  • ノードは、書き込みトランザクションを受け入れることができる場合は常に、最新のリーダーとしてマークする必要があります。Patroniがクラッシュしたり、PostgreSQLがシャットダウンしないと、この不変式に違反が発生する可能性があります。

  • ノードは、同期スタンバイとして公開されている限り、PostgreSQLで同期スタンバイとして設定する必要があります。

  • リーダーまたは現在の同期スタンバイではないノードは、自分自身を自動的に昇格することはできません。

Patroniは、 synchronous_node_count パラメーターに基づいて1つ以上の同期スタンバイノードのみを synchronous_standby_names に割り当てます。

HAループの反復ごとに、Patroniは同期スタンバイノードの選択を再評価します。同期スタンバイノードの現在のリストが接続されており、その同期ステータスの削除を要求していない場合、選択されたままになります。それ以外の場合、レプリケーションで最も先にある同期に使用可能なクラスターメンバーが選択されます。