スマートスタイル TECH BLOG

データベース&クラウド技術情報

Orchestrator Raft Cluster による HA構成 【第1回】

今回の記事では MySQL レプリケーショントポロジーの管理ツール Orchestrator の HA 構成について紹介します。

Orchestrator は MySQL レプリケーション環境の自動フェイルオーバーリカバリを行ってくれるのが主な役割ですが、本番環境など可用性が求められる環境では Orchestrator 自体の保護だったり、単一障害点とならない設計が必要となってきます。

要は、Orchestartor に障害が発生しても、MySQL レプリケーション管理&フェイルオーバ―リカバリが可能な状態を継続させる、ということが求められることになります。

HA 構成パターン

Orchestrator には HA 構成の選択肢が幾つか用意されています。
詳細については、以下の公式ドキュメントをご一読ください。

orchestrator/high-availability.md

そのうち、特に単一障害点を持たないようにする構成としては以下の2つのパターンのいずれかになります。

  1. リポジトリDB を Galera Cluster/PXC, InnoDB Cluster, NDB Cluster といった同期型共有DBバックエンドにする

    • Orchestrator ノードは複数台用意するが、基本的には単一ノードから操作(書込み)するように制限する
    • バックエンドDB 上記 RDBMS の最低必要台数はいずれも3台
    • → 全体で最低5台必要となる

  2. raft を用いたクラスター構成にする(orchestrator/raft)

    • Orchestrator ノードは複数台(3台以上奇数台)用意し、各ノードは hashicorp/raft を用いて raft コンセンサスにより調整して動く(書込みはリーダーノードのみで行われる)
    • バックエンド DB は各 Orchestrator ノードに紐づくスタンドアロン DB (MySQL または SQLite を選択可能)
    • → 全体で最低3台必要となる
    • orchestrator/raft に関する公式ドキュメント:orchestrator/raft.md

上記 1,2 それぞれの構成における対比表が公式ドキュメントで纏められていますので、こちらをご確認いただくのが最も分かり易いです。

orchestrator/raft-vs-sync-repl.md

raft クラスターの要点をまとめると以下となります。

  • raft コンセンサスアルゴリズム
  • クォーラムベースのリーダー選出
  • raft レプリケーションログ
  • スナップショットの取得・リストア
  • 全メンバーが以下の処理を実行する
    • レプリケーショントポロジーの検出・探査
    • レプリケーショントポロジーの障害検出
    • 自ノードのヘルスチェック結果登録
  • リーダーノードのみが以下の処理を実行する
    • リカバリ
    • 任意の状態変更系コマンド実行
    • HTTP リクエスト

そして上記ドキュメント内の Considerations にはどの構成を選ぶのがよいかガイダンスが示されています。

ただし、最小必要台数・スケーラビリティ・セットアップやリカバリの機能性を考慮すると raft クラスター構成を選択するのが現時点では一般的な推奨ではないかと考えます。

今回の内容は、以下の2回構成でお送りしたいと思います。

  • 第1回:セットアップ方法の紹介と、基本的な障害時挙動について
  • 第2回:障害ノードのリカバリ方法、クロス DC (データセンター)構成の MySQL レプリケーションフェイルオーバーリカバリとフェンシングについて

orchestrator/raft のセットアップ

検証環境

  • 3ノード共通
    • Rocky Linux release 8.6 (Green Obsidian)
    • Orchestrator v3.2.6
ホスト名 IP アドレス
rha-orc-01 172.19.56.119
rha-orc-02 172.19.56.120
rha-orc-03 172.19.56.121

パラメータ設定

raft クラスターの構成方法は以下のドキュメントに記載されています。

orchestrator/configuration-raft.md

/etc/orchestrator.conf.json を以下のように編集します。

(rha-orc-01 の場合)

RaftNodes には RaftBind に設定した自ノードを含むすべてのクラスターノードを列挙する必要があります。

全クラスターノードで orchestrator を起動すると、ノード間で raft 通信が開始されます。

orchestrator ログファイルには、DEBUG レベルでログ出力させていると raft 関連のロギングが多量に出力されます。

こちらは rha-orc-02 (172.19.56.120) のログ抜粋ですが、raft リーダーに選出されています。

rha-orc-03 (172.19.56.121) のログには、リーダーが 172.19.56.120 で、自分はフォロワー(state: Follower)であることが出力確認できます。

orchestrator-client 用の追加設定

orchestrator バイナリは単体で CLI コマンドを実行することができるのですが、 raft クラスター構成の場合、以下のエラーで実行できません。

エラーメッセージに記載されている通り、--ignore-raft-setup オプションを付与すれば実行は可能です。(--quietオプションは 2>/dev/null と同義です)

このエラーの対応方法は以下のページに記載されています。

orchestrator/deployment-raft.md – What to deploy: client

(本家 Github リポジトリには raft に関する公式ドキュメントが散在している状態なのでなかなか見つけ辛いですが…)

raft クラスター構成の場合、リーダーノードで管理操作(特に変更系)を行うことが必要ですが、 orchestrator バイナリの CLI コマンドはローカルの DB に直接アクセスしに行くので、自ノードが リーダーノードなのか判断できないため敢えて実行エラーとしているのです。

対応方法としては、orchestrator-client を実行する OS ユーザの .bash_profile、もしくは OS ログインユーザ全体に適用させるなら /etc/profile.d/orchestrator-client.sh を作成して以下の環境変数を設定します。(※名前解決できる前提)

この設定方法の場合、orchestrator-client が raft リーダーを自動判別してくれます。

上記マニュアルにも記載ある通り、もし raft リーダーにプロキシするエンドポイントを設定済みなら、以下のように設定してもかまいません。

※以下のドキュメントページに HAProxy でセットアップする例が記載されていますのでご参考までに。

orchestrator/raft.md – Proxy: leader

RaftDataDir

RaftDataDir パラメータに指定したディレクトリには、raft のイベントログとスナップショットが格納されます。

スナップショットは、Orchestrator がノードダウン後、クラスタに再参加したときに、他のアクティブなノードから最新のスナップショットを取得してダウン中に発生していたイベントを漏れなく取得することができます。

Web 管理コンソール上の表示

raft クラスターの状態は、Web 管理コンソールにログイン後、 Home > Status と辿ると確認することができます。

リーダーノード のステータス画面にのみ、raft メンバーが表示されます。

(以下の例は rha-orc-02 がリーダーノードの場合)

フォロワーノードでは他メンバーは表示されない仕様のようです。

リーダーノードの確認と手動選出の CLI コマンド

以下の CLI コマンドで現在のリーダーノードを確認できます。

リーダーノードに設定するには raft-elect-leader コマンドを実行します。
以下は、自ノードをリーダーノードに設定するコマンド例です。

平常時にリーダーノードがダウンした場合

まずは基本動作の確認です。

rha-orc-03 のログから Orchestrator プロセスが停止したのを確認します。

rha-orc-01 のログでは、rha-orc-03 とのハートビートがタイムアウト後、リーダー選出が開始され、このノードがリーダーとなった様子が確認できます。

rha-orc-02 のログでは、このノードはフォロワー(変わらず)という結果が確認できます。

CLI コマンドでも、新しいリーダーノードである rha-orc-01 が確認できました。

rha-orc-03 の Orchestrator サービスを再び起動します。

ローカルノードに取得していたスナップショットをリストアした後、アクティブな他ノードからログを取得し適用、クラスターに再参加する動きとなります。

レプリケーションソースフェイルオーバー中にリーダーノードがダウンした場合

つぎに、管理している MySQL レプリケーショントポロジーのソースDBがダウンしフェイルオーバーリカバリを実行中のケースを確認します。

通常時のレプリケーショントポロジーが以下の状態です。

ソース mysqld を停止しました。

rha-orc-01 のリカバリフック実行ログに PreFailoverProcesses で仕込んでおいたスクリプトの実行が確認できます。
実際のリカバリ処理(新ソースへのフェイルオーバ処理)が動く直前のステップです。
(このスクリプトには今回の検証のため sleep を入れています)

このタイミングで リーダーノードの orchestrator プロセスを強制停止します。

rha-orc-03 のリカバリフック実行ログを確認すると、DeadMaster のリカバリステップから処理が継続されています。

rha-orc-03 がリーダーノードとなったためです。

独自のスクリプトをフックさせて実行させている途中で Orchestrator のフェイルオーバが起こった場合は、流石にスクリプト内の処理を継続したりリカバリしたりはできないので、それはユーザー側の責任範疇です。
障害時を想定したアトミックまたはフェイルセーフなコーディングを心掛けたいところです。

rha-orc-03 の Orchestrator ログで raft によるリカバリ処理のフェイルオーバ状況が確認できます。

結果、レプリケーションフェイルオーバーリカバリが完遂しました。

Orchestrator リポジトリDBスキーマが消失や破損した場合

リポジトリDB のスキーマ(※) が消失したり破損した場合、Orchestrator サービスはダウンします。
※スキーマ名は MySQLOrchestratorDatabase パラメータで定義。デフォルトは orchestrator

フェイルオーバーリカバリ中に発生した場合は、前述と同じように他のメンバーノードで処理がフェイルオーバー(継続)されます。

ダウンした Orchestrator を再び起動させれば、起動時に DB スキーマおよびテーブルは内部的に再作成されます。

その後、raft スナップショットのリストアおよびクラスタメンバーからの raft ログ適用によって、最新状態までリカバリされます。

まとめ

今回の記事では、Orchestrator raft クラスターのセットアップと障害時挙動(フェイルオーバー、リカバリの継続実行)について確認しました。

パラメータを設定するだけの非常にシンプルなセットアップで HA 構成が組めることが特徴的です。

また、目的である冗長化による Orchestrator のサービス継続性も高まることがお分かりいただけたかと思います。

続き記事として、次回は以下のドキュメントにも紹介されている DC fencing (複数データセンターに分散配置させた場合のフェイルオーバーリカバリ時のフェンシング)の挙動について確認してみたいと思います。

orchestrator/raft.md – DC fencing example

Return Top