自動フェイルオーバー
====================
.. raw:: html
プライマリで予期しないエラーが\ ``.spec.failoverDelay``
デフォルトでは\ ``0`` 秒より長く発生した場合、クラスターは
**フェールオーバーモード**
になります。これは、たとえば次の場合に発生する可能性があります。
- プライマリポッドにディスク障害が発生した
- プライマリポッドが削除された
- プライマリの\ ``postgres`` コンテナに何らかの持続的な障害がある
フェールオーバーシナリオでは、プライマリが正常に動作していると想定できません。
上記のような場合の後、プライマリポッドの準備状況プローブは失敗し始めます。これは、コントローラの調整ループで取得されます。コントローラは、2つの手順でフェールオーバープロセスを開始します。
1. 最初に、\ ``TargetPrimary`` を\ ``pending``
としてマークします。この状態の変更は、プライマリポッドを強制的にシャットダウンし、レプリカのWALレシーバーが停止します。クラスターは、フェールオーバーフェーズ「フェールオーバー」でマークされます。
2. すべてのWALレシーバーが停止すると、リーダー選挙が行われ、新しい予備選挙が名前付けられます。選択されたインスタンスはプライマリへの昇格を開始し、これが完了すると、クラスターは通常のオペレーションを再開します。一方、以前のプライマリポッドは再起動し、プライマリでなくなったことを検出し、レプリカノードになります。
.. Important::
2フェーズプロシージャは、WALレシーバーが正常に停止でき、障害が発生したプライマリが再起動時にWALのストリーミングを再度開始しないことを保証します。これらの安全対策は、新しいプライマリとレプリカ間のタイムラインの不一致を防ぎます。
障害が発生したプライマリがシャットダウンされている間
1. 最初に\ ``.spec.switchoverDelay`` 秒をタイムアウトとしてPostgreSQLの
*高速シャットダウン*
を試行します。この正常なシャットダウンは、保留中のWALをアーカイブしようとします。
2. 高速シャットダウンが失敗するか、そのタイムアウトを超過すると、PostgreSQLの
*即時シャットダウン* が開始されます。
.. Note::
「Fast」モードは、PostgreSQLクライアントが切断されるのを待機せず、進行中のオンラインバックアップを終了します。アクティブなトランザクションはすべてロールバックされ、クライアントは強制的に切断され、サーバーはシャットダウンされます。 「Immediate」モードは、クリーンシャットダウンせずに、すべてのPostgreSQLサーバープロセスをすぐに中止します。
RTOとRPOのインパクト
--------------------
フェイルオーバーにより、サービスが影響を受ける :ref:`RTOとRPOのインパクト `
および/またはデータが失われる :ref:`PgBouncerPoolMode {postgresql-cnpg-io-v1-PgBouncerPoolMode} ` が発生する場合があります。
1. プライマリに障害が発生し始め、コントローラがフェールオーバー手順を開始する前に、転送中のクエリ、WAL書き込み、チェックポイントおよび同様の操作が失敗する場合があります。
2. fast
shutdownコマンドが発行されると、クラスターは接続を受け入れなくなるため、サービスは影響を受けますが、データは失われません。
3. 高速シャットダウンが失敗した場合、即時シャットダウンはWAL書き込みを含む保留中のプロセスを停止します。データが失われる可能性があります。
4. プライマリがシャットダウンしており、新しいプライマリがまだ起動していない間、クラスターはプライマリなしで動作するため、機能が低下しますが、データの損失はありません。
.. Note::
高速シャットダウンを制御するタイムアウトは、スイッチオーバーの場合と同様に`.spec.switchoverDelay` によって設定されます。高速シャットダウンの時間を長くすることは、RPOの観点からより安全ですが、通常のオペレーションへの復帰が遅延する可能性があり、RTOに悪影響を及ぼします。
.. Warning::
:ref:`インスタンスマネージャーのインプレース更新 <インスタンスマネージャーのインプレース更新>` で既に述べたように
スイッチオーバープロセスを説明するとき、 ``.spec.switchoverDelay``
オプションはPostgreSQLデータベースのRPOとRTOに影響を与えます。低い値に設定すると、RPOよりもRTOが優先される場合がありますが、クラスターレベルおよび/またはバックアップレベルでデータの損失が発生します。逆に、高い値に設定すると、スイッチオーバー中にアクティブなプライマリのないクラスターを長時間放置する間のデータ損失のリスクを取り除くことができます。
遅延フェイルオーバー
--------------------
上記で予想されたように、 ``.spec.failoverDelay``
オプションを使用すると、プライマリが異常であると検出された後、フェイルオーバープロシージャの開始を秒単位で遅延できます。デフォルトでは、この設定は\ ``0``
に設定され、フェイルオーバー手順がすぐにトリガーされます。
場合によっては、新しいプライマリへのフェイルオーバーの方が、プライマリがオンラインに戻るのを待つよりも混乱を招く可能性があります。これは、複数の層が影響を受けるダウンストリーム論理サブスクライバー、またはフェールオーバーの実行時間が予想される停止よりも長い場合、ネットワークの中断に特に当てはまります。
フェールオーバーを遅延する新しい構成オプションを有効にすることにより、短期間のネットワークまたはノードの不安定性による時期尚早のフェールオーバーを防止するメカニズムを提供します。
Failover Quorum クォーラムベースのフェールオーバー
--------------------------------------------------
.. Warning::
*フェールオーバークォーラム*は、バージョン1.27.0で導入された実験的な機能です。運用環境では注意して使用します。
フェールオーバークォーラムは、CloudNativePG管理のPostgreSQLクラスターでのフェールオーバーイベント中のデータの耐久性と安全性を強化するメカニズムです。
クォーラムベースのフェールオーバーにより、コントローラーは、レプリカのクォーラムの状態に基づいて、レプリカをプライマリにプロモートせるかどうかを決定します。これは、
:ref:`同期レプリケーションを介したゼロデータ損失クラスター <同期レプリケーションを介したゼロデータ損失クラスター>` およびデフォルトの自動フェイルオーバープロシージャが提供するものよりも強力なデータの耐久性が必要な場合に役立ちます。
同期レプリケーションが有効になっていない場合、レプリカは昇格時にプライマリよりも遅延する場合があるため、フェールオーバー中にある程度のデータ損失が予想され受け入れられます。
同期レプリケーションが有効になっている場合、保証は、必要なすべての同期スタンバイがWALデータを安全に受信したことが判明するまで、アプリケーションがトランザクションの成功したコミットの明示的な確認を受け取らないことです。これは、オペレーターが最新のレプリカをプロモーションできることを保証するのに十分ではありません。
たとえば、同期レプリケーションが\ ``ANY 1 (...)``
に設定されている3ノードクラスターでは、コミットが確認される前にデータがプライマリと1つのスタンバイに書き込まれます。プライマリとアラインメントされたスタンバイの両方が使用不可になる場合ネットワーク分割中など、残りのレプリカには最新のデータがない場合があります。それを昇格させると、アプリケーションがコミットしたと考えられる一部のデータが失われる可能性があります。
クォーラムベースのフェイルオーバーは、オペレーターがプロモートするインスタンスに同期コミットされたデータの存在を確認できる場合にのみフェイルオーバーが発生し、それ以外の場合は発生しないようにすることにより、このリスクに対処します。
この機能を使用すると、ユーザーはデータの耐久性とデータの可用性の間で好みのトレードオフを選択できます。
フェールオーバークォーラムは、 ``Cluster``
リソースにアノテーション\ ``alpha.cnpg.io/failoverQuorum="true"``
を設定することにより有効にできます。
.. Note::
この機能が実験フェーズを終了すると、アノテーション `alpha.cnpg.io/failoverQuorum` は`Cluster` リソースの構成オプションに置き換えられます。
仕組み
^^^^^^
レプリカをプライマリに昇格する前に、オペレーターはDynamo ``R + W > N``
一貫性モデル[^1]の原則に従って、クォーラムチェックを実行します。
クォーラムフェイルオーバーでは、これらの値は次の意味を想定しています。
- ``R`` は、 *プロモートブルレプリカ* 読み取りクォーラムの数です。
- ``W`` は、 ``COMMIT``
がクライアント書き込みクォーラムに返される前に、書き込みを確認する必要があるレプリカの数です。
- ``N`` は、同期している可能性のあるレプリカの合計数です。
*プロモーブルレプリカ* は、次のプロパティを持つレプリカです。
- クラスターの一部です。 -自分の状態をオペレーターに報告できます。 -
潜在的に同期しています。
``R + W > N``
の場合、プロモートブルレプリカの中に、すべての同期コミットを確認した少なくとも1つがあることを確認でき、安全にプライマリに昇格できます。これに当てはまらない場合、コントローラはレプリカをプライマリにプロモートせず、状況が変化するまで待機します。
クォーラムチェックが失敗した場合でも、ユーザーは\ ``kubectl cnpg promote``
コマンドを使用してレプリカをプライマリに強制的にプロモーションできます。
.. Warning::
手動プロモーションは最後の手段としてのみ使用してください。続行する前に、データ損失のリスクを十分に理解し、アプリケーションの書き込みワークロードの再開を優先した場合の影響を注意深く検討してください。
追加のCRDは、クラスターのクォーラム状態を追跡するために使用されます。クォーラムフェイルオーバーが有効になった\ ``Cluster``
には、 ``Cluster`` リソースと同じ名前の\ ``FailoverQuorum``
リソースがあります。 ``FailoverQuorum``
CRは、クォーラムフェイルオーバーが有効になっているときにコントローラによって作成され、調整ループ中にプライマリインスタンスによって更新され、クォーラムチェック中にオペレーターによって読み取られます。これは、同期レプリケーションの最新の既知の構成を追跡するために使用されます。
.. Important::
ユーザーは`FailoverQuorum` リソースを直接変更しないでください。 PostgreSQLの構成の変更中に、構成を決定できない場合、`FailoverQuorum` リソースがリセットされ、新しい構成が適用されるまでフェイルオーバーを防止します。
``FailoverQuorum``
リソースは、PostgreSQL同期レプリケーションと連携して動作します。
.. Warning::
`SET synchronous_commit TO local` で同期レプリケーションを明示的に無効にして作成された操作など、クライアントに返されたが同期的に実行されていない`COMMIT` 操作が、昇格したレプリカに存在するという保証はありません。
クォーラムフェイルオーバーの例
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
次のシナリオでは、 ``R`` はプロモーブルレプリカの数、\ ``W``
はコミット前に書き込みを確認する必要があるレプリカの数、および\ ``N``
は潜在的な同期レプリカの合計数です。
「Failover」列は、クォーラムフェールオーバールールでフェールオーバーが許可されるかどうかを示します。
シナリオ13ノードクラスター、障害のあるポッド
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``instances: 3`` 、\ ``synchronous.number=1``
、および\ ``dataDurability=required`` を含むクラスター。
- プライマリにのみ障害が発生した場合、2つのプロモーション可能なレプリカが残りますR=2。
``R + W > N`` (2 + 1 > 2)以降、フェイルオーバーが許可され安全です。
- プライマリと1つのレプリカの両方に障害が発生した場合、1つのプロモートブルレプリカR=1のみが残ります。
``R + W = N`` 1 + 1 =
2ため、データ損失の可能性を防ぐために、フェイルオーバーは許可されません。
.. csv-table::
:header: R,W,N,Failover
:widths: 15,12,12,20
:align: left
:class: longtable
2,1,2,OK
1,1,2,NO
シナリオ23ノードクラスター、ネットワークパーティション
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``instances: 3`` 、\ ``synchronous.number: 1``
、および\ ``dataDurability: required``
を含むクラスターでネットワークパーティションが発生します。
- オペレーターがプライマリと通信できる場合、フェールオーバーは発生しません。プライマリがスタンバイに到達できない場合、クラスターは同期レプリケーション要件によりトランザクションをコミットしないため、クラスターは影響を受ける可能性があります。
- オペレーターがプライマリに到達できないが、両方のレプリカR=2に到達できる場合、フェールオーバーは許可されます。オペレーターが1つのレプリカR=1のみに到達できる場合、同期的なものは別のレプリカである可能性があるため、フェールオーバーは許可されません。
.. csv-table::
:header: R,W,N,Failover
:widths: 15,12,12,20
:align: left
:class: longtable
2,1,2,OK
1,1,2,NO
シナリオ35ノードクラスター、ネットワークパーティション
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``instances: 5`` 、\ ``synchronous.number=2``
、および\ ``dataDurability=required``
を含むクラスターでネットワークパーティションが発生します。
- オペレーターがプライマリと通信できる場合、フェールオーバーは発生しません。プライマリが少なくとも2つのスタンバイに到達できない場合、同期レプリケーション要件のためにトランザクションをコミットしないため、クラスターは影響を受ける可能性があります。
- オペレーターがプライマリに到達できないが、少なくとも3つのレプリカR=3に到達できる場合、フェールオーバーは許可されます。オペレーターが2つのレプリカR=2のみに到達できる場合、同期的なものがもう一方である可能性があるため、フェールオーバーは許可されません。
.. csv-table::
:header: R,W,N,Failover
:widths: 15,12,12,20
:align: left
:class: longtable
3,2,4,OK
2,2,4,NO
シナリオ4リモート同期レプリカを使用した3ノードクラスター
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``instances: 3`` と\ ``standbyNamesPre`` または\ ``standbyNamesPost``
で定義されたリモート同期レプリカを含むクラスター。プライマリに障害が発生していると仮定します。
このシナリオでは、重要な考慮事項が必要です。 ``standbyNamesPre``
または\ ``standbyNamesPost`` にリストされているレプリカは、\ ``R``
ではカウントされません昇格することはできませんが、 ``N``
に含まれます同期書き込みを受信した可能性があります。したがって、
``synchronous.number <= len(standbyNamesPre) + len(standbyNamesPost)``
の場合、ローカルレプリカが必要なデータを持つことを保証できないため、フェイルオーバーは不可能です。オペレーターは検証中にこのような構成を防止しますが、明確にするためにいくつかの無効な構成を以下に示します。
**構成例**
構成1有効
.. code:: yaml
instances: 3
postgresql:
synchronous:
method: any
number: 2
standbyNamesPre:
- angus
この構成では、プライマリに障害が発生すると、 ``R = 2``
ローカルレプリカ、\ ``W = 2``
、およびつのローカルレプリカ+1つのリモートでフェールオーバーが可能になります。追加のレプリカに障害\ ``R = 1``
が発生した場合、フェイルオーバーは許可されません。
.. csv-table::
:header: R,W,N,Failover
:widths: 15,12,12,20
:align: left
:class: longtable
3,2,4,OK
2,2,4,NO
構成2無効
.. code:: yaml
instances: 3
postgresql:
synchronous:
method: any
number: 1
maxStandbyNamesFromCluster: 1
standbyNamesPre:
- angus
この構成では、 ``R = 2`` ローカルレプリカ、\ ``W = 1``
、およびローカルレプリカ+1リモート。この設定ではフェールオーバーは不可能であるため、この構成ではクォーラムフェールオーバーを有効にできません。
.. csv-table::
:header: R,W,N,Failover
:widths: 15,12,12,20
:align: left
:class: longtable
1,1,2,NO
構成3無効
.. code:: yaml
instances: 3
postgresql:
synchronous:
method: any
number: 1
maxStandbyNamesFromCluster: 0
standbyNamesPre:
- angus
- malcolm
この構成では、 ``R = 0`` ローカルレプリカ、\ ``W = 1``
、およびローカルレプリカ+2リモート。この設定ではフェールオーバーは不可能であるため、この構成ではクォーラムフェールオーバーを有効にできません。
.. csv-table::
:header: R,W,N,Failover
:widths: 15,12,12,20
:align: left
:class: longtable
0,1,2,NO
シナリオ53ノードクラスター、優先データ耐久性、ネットワークパーティション
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ネットワークパーティションが発生した\ ``instances: 3``
、\ ``synchronous.number=1`` 、および\ ``dataDurability=preferred``
を含むクラスターを検討します。
- オペレーターがプライマリとAPIサーバーの両方と通信できる場合、プライマリは動作を継続し、到達不能なスタンバイを\ ``synchronous_standby_names``
セットから削除します。
- プライマリがオペレーターまたはAPIサーバーに到達できない場合、クォーラムチェックが実行されます。プライマリは新しい構成を受信できないため、
``FailoverQuorum``
ステータスは変更されることはできません。オペレーターが両方のレプリカに到達できる場合、フェイルオーバーが許可されます
``R=2`` 。 1つのレプリカ\ ``R=1``
のみが到達可能である場合、フェイルオーバーは許可されません。
.. csv-table::
:header: R,W,N,Failover
:widths: 15,12,12,20
:align: left
:class: longtable
2,1,2,OK
1,1,2,NO
`^1 `_