スイッチオーバー

スイッチオーバーは、データを失うことなくプライマリとスタンバイの方向を変更します。現在のプライマリクラスタにまだ到達可能な場合、またはメンテナンスのためにトラフィックを移動する必要がある場合に使用します。

このガイドでは、現在のトポロジーを想定しています:

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

スイッチオーバー後のトポロジーは次のようになります:

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

スイッチオーバーを使用するタイミング

次の場合にスイッチオーバーを使用します:

  • 現在のプライマリでメンテナンスを行っている。
  • プライマリが部分的にデグレードしているが、まだ要求に応答できる。
  • RPO=0が必要で、データ損失を許容できない。

プライマリが完全に利用できない場合は、スイッチオーバーを使用しないでください。その場合はフェイルオーバーを使用してください。

開始する前に

開始前に以下を確認してください:

  • 両方のクラスタに到達可能である。
  • CDCレプリケーションが正常である。
  • CDCの遅延がリカバリ時間の目標に対して十分に小さい。
  • 役割の変更中にアプリケーションの書き込みを一時停止または再試行できる。
  • 新しいトポロジー構成を準備している。

スイッチオーバーではデータ損失がないことが保証されますが、操作時間はレプリケートされるデータの残量に依存します。

新しいトポロジーの構築

cluster-b がソースになり、cluster-a がターゲットになる完全置換構成を作成します。

# If you followed Set Up CDC Replication, cluster A is the original source cluster,
# and cluster B is the original target cluster.
cluster_a_id = source_cluster_id
cluster_a_addr = source_cluster_addr
cluster_a_client_addr = source_client_addr
cluster_a_token = source_cluster_token
cluster_a_pchannels = source_cluster_pchannels

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

switchover_config = {
    "clusters": [
        {
            "cluster_id": cluster_a_id,
            "connection_param": {
                "uri": cluster_a_addr,
                "token": cluster_a_token,
            },
            "pchannels": cluster_a_pchannels,
        },
        {
            "cluster_id": cluster_b_id,
            "connection_param": {
                "uri": cluster_b_addr,
                "token": cluster_b_token,
            },
            "pchannels": cluster_b_pchannels,
        },
    ],
    "cross_cluster_topology": [
        {
            "source_cluster_id": cluster_b_id,
            "target_cluster_id": cluster_a_id,
        }
    ],
}

新しいトポロジーの適用

両方のクラスタに同じ構成を適用します。まず現在のプライマリにリクエストを送信し、次にスタンバイに送信します。後で元に戻す場合は、cluster-b が現在のプライマリであるため、順序を逆にします。

from pymilvus import MilvusClient

client_a = MilvusClient(uri=cluster_a_client_addr, token=cluster_a_token)
client_b = MilvusClient(uri=cluster_b_client_addr, token=cluster_b_token)

try:
    client_a.update_replicate_configuration(**switchover_config)
    client_b.update_replicate_configuration(**switchover_config)
finally:
    client_a.close()
    client_b.close()

古いプライマリはスタンバイに降格し、新しい書き込みを拒否します。古いスタンバイはレプリケートされたデータの残りを待ち、自身をプライマリに昇格させ、書き込みを受け付ける。

一時的なネットワークエラーやサービスエラーで要求が失敗した場合は、同じ構成で再試行してください。

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

cluster-b がプライマリになった後:

  1. 書き込みトラフィックをcluster-b に向ける。
  2. cluster-b で読み取りと書き込みが成功することを確認する。
  3. cluster-a がアプリケーションの書き込みを受信しなくなったことを確認する。
  4. cluster-b からcluster-a へのレプリケーションを監視し続ける。

結果の検証

cluster-b が新しいプライマリとして機能し、データの一貫性が保たれていることを確認する。一般的なチェックは以下のとおりです:

  • 重要なコレクションの行数を比較する。
  • 両方のクラスタから既知のプライマリ・キーをクエリします。
  • 新しいプライマリと古いスタンバイで代表的な検索を実行します。
  • cluster-b に小規模な書き込みを実行し、それがcluster-a にレプリケートされることを確認します。

スイッチ・バック

後でスイッチ・バックするには、元のトポロジーを再度適用します:

cluster-a -> cluster-b

同じ切り替えフローを使用する。現在のプライマリに到達可能で、レプリケーションが健全であることを確認してからスイッチバックします。

よくある質問

スイッチオーバーするとデータは失われますか?

いいえ。スイッチオーバーでは、スタンバイがプライマリになる前に、残りのデータがレプリケートされるのを待ちます。

アプリケーションの書き込みを停止する必要がありますか?

役割の変更中は、書き込みを一時停止するか、書き込みを再試行可能にする必要があります。古いプライマリが降格した後に送信された書き込みは拒否されます。

切り替えに予想以上に時間がかかるのはなぜですか?

最も一般的な理由はCDCラグです。新しいプライマリがRPO = 0で安全に引き継ぐには、残りのデータを受信する必要があります。

スイッチオーバーに失敗したリクエストを再試行できますか?

可能です。同じターゲット・トポロジーで再試行してください。

古いプライマリはどうなりますか?

古いプライマリはスタンバイになります。アプリケーションの書き込みを受け取らなくなります。