フェイルオーバー

フェイルオーバーは、元のプライマリが完全に利用できなくなった場合に、スタンバイクラスタをスタンドアロンのプライマリに昇格させます。これは可用性優先の操作であり、障害前にレプリケートされていなかったデータが失われる可能性があります。

このガイドでは、元のトポロジを前提としています:

cluster-a (primary)  ->  cluster-b (standby)

フェイルオーバー後、cluster-b はスタンドアロンのプライマリになります:

cluster-b (primary)

フェイルオーバーを使用するタイミング

フェイルオーバーは、以下の場合にのみ使用してください:

  • 元のプライマリが要求に応答できない。
  • プライマリを許容時間内に回復できない。
  • 書き込み可用性を回復することの方が、古いプライマリを待つことよりも重要である。

プライマリにまだ到達可能な場合は、代わりにスイッチオーバーを使用します。スイッチオーバーにより、データ損失を回避できます。

データ損失のリスク

フェイルオーバーでは、元のプライマリを待つことはありません。旧プライマリに書き込まれ、スタンバイにまだレプリケートされていないデータは失われる可能性があります。

データ損失の可能性は、プライマリが使用できなくなった時点のCDCラグによって決まります。

フェイルオーバーを実行する前に、トレードオフを理解してください:

目標スイッチオーバーフェイルオーバー
プライマリがアクセスできない間に書き込みをリストアするいいえ
データ損失の回避保証なし
旧プライマリの応答が必要保証なし保証しない

始める前に

以下を確認してください:

  • 元のプライマリが使用できない。
  • プライマリの復旧を待たないことにした。
  • アプリケーション・トラフィックをスタンバイにリダイレクトできる。
  • トラフィック・オートメーションが回復しても、古いプライマリに書き込みを送り返さない。
  • スタンバイ・クラスタID、アドレス、トークン、およびpchannelsを持っている。

最も重要な安全要件はスプリットブレインを防ぐことです。フェイルオーバー後、昇格したスタンバイだけがアプリケーションの書き込みを受け付けるようにします。

フェイルオーバー構成の構築

スタンバイ・クラスタのみを含み、レプリケーション・トポロジを含まない構成を構築します。force_promote=True を設定します。

# If you followed Set Up CDC Replication, cluster B is the original target cluster.
cluster_b_id = target_cluster_id
cluster_b_addr = target_cluster_addr
cluster_b_client_addr = target_client_addr
cluster_b_token = target_cluster_token
cluster_b_pchannels = target_cluster_pchannels

failover_config = {
    "clusters": [
        {
            "cluster_id": cluster_b_id,
            "connection_param": {
                "uri": cluster_b_addr,
                "token": cluster_b_token,
            },
            "pchannels": cluster_b_pchannels,
        }
    ],
    "cross_cluster_topology": [],
    "force_promote": True,
}

スタンバイのプロモート

リクエストをスタンバイ・クラスタに送信します。

from pymilvus import MilvusClient

client_b = MilvusClient(uri=cluster_b_client_addr, token=cluster_b_token)

try:
    client_b.update_replicate_configuration(**failover_config)
finally:
    client_b.close()

要求が成功すると、cluster-b はスタンドアロンのプライマリになり、書き込みを受け付けることができます。

アプリケーション・トラフィックのリダイレクト

昇格後:

  1. 書き込みトラフィックをcluster-b にリダイレクトします。
  2. 書き込みエンドポイント、ロードバランサー、DNSレコード、および自動化からcluster-a
  3. cluster-b が書き込みを受け付けることを確認する。
  4. cluster-a は、廃止されるか明示的に再構築されるまで隔離しておく。

書き込みの検証例:

client_b = MilvusClient(uri=cluster_b_client_addr, token=cluster_b_token)

try:
    client_b.insert(
        collection_name="test_collection",
        data=[{"id": 1, "vector": [0.1] * 128}],
    )
finally:
    client_b.close()

コレクション名とスキーマフィールドを、デプロイメントに合わせて調整する。

結果の検証

プロモートされたクラスタを直接検証します:

  • 書き込みはcluster-b で成功します。
  • 読み取りは期待されるデータを返します。
  • cluster-a へのアプリケーション・コンポーネントの書き込みはありません。

古いプライマリの処理

フェイルオーバー後、cluster-a をステールとして扱います。再び到達可能になった場合は、アプリケーションの書き込みを送信しないでください。cluster-b にレプリケー トされなかったデータが含まれている可能性があり、フェイルオーバー後にcluster-b に新しい書き込みが既に含まれている可能性があります。

cluster-a を古いトポロジーに自動的に再接続しないでください。古いプライマリの再導入は、慎重に計画する必要がある別の復旧作業です。

データ損失の最小化

フェイルオーバーによるデータ損失のリスクをすべて取り除くことはできませんが、減らすことはできます:

  • CDCのラグを継続的に監視する。
  • プライマリの書き込みレートを処理できるようにスタンバイ・クラスタをプロビジョニングしておく。
  • クロス・クラスタのネットワーク・レイテンシとパケット・ロスを低く抑える。
  • アプリケーションの書き込みを偶発的なものにする。
  • フェイルオーバー後に成功が不確実な書き込みを再試行する。
  • プライマリがまだ応答できる場合は、いつでも切り替えを優先する。

よくある質問

フェイルオーバーすると必ずデータが失われますか?

いいえ。プライマリに障害が発生する前にすべての書き込みがすでにレプリケートされていた場合、データは失われません。CDCのラグが存在する場合、ラグのあるデータが失われる可能性があります。

フェイルオーバーにはどのくらい時間がかかりますか?

スタンバイのクラスタ状態と制御プレーンの可用性によりますが、通常は数秒以内に完了します。

プライマリでフェイルオーバーを実行できますか?

フェイルオーバーはスタンバイクラスタを対象としています。現在のプライマリが利用可能な場合は、スイッチオーバーを使用してください。

古いプライマリは自動的に再参加できますか?

いいえ。フェイルオーバー後、古いプライマリが再びレプリケーションに参加できるようになるには、古いプライマリをステールとして扱い、退役させるか再構築する必要があります。

スプリットブレインを回避するにはどうすればよいですか?

昇格したクラスタのみが書き込みを受け取るようにします。復旧してトラフィックを受け付ける前に、すべての書き込みパスから古いプライマリを削除します。