SeveralninesのMySQL High Availability tools - Comparing MHA, MRM and ClusterControl を興味深く読みました。この比較には不足しているものがあるのではないかと思いました: それはorchestratorであり、結果として比較範囲と内容が不足していました。
※訳注: MRM: MariaDB Replication Manager
私は記事で言及されているテーマに対して自分の意見を付け加えたいと思います。私は全くもってMHA、MRMあるいはClusterControlの専門家ではありませんので、orchestratorが記事で取り上げられている高可用の問題にどのように取り組んでいるかに焦点を当てたいと思います。
この記事について
この記事はフェイルオーバーの複雑さについての見識を広めるためのものです。3年間にわたってありとあらゆることを見てきていますが、それでもまだ常軌を逸した状況に出くわします。正しいことを自動的に行うのは難しいのです。
この記事では、あなたにorchestratorを利用するように説得するわけではありません(ですが利用してくれたらうれしいです)。誤解のないようにいうと、他のどのツールよりorchestratorがよいとはいいません。いつもそうであるように、それぞれのツールに長所短所があります。
この記事は他のツールが良くないと主張するものでもありません。またorchestratorが全ての答えを導くというものでもありません。最後にあなたにとって一番良い解決策を選んでみてください。私は99.99%のケースに対応できるといっている信頼できない方法よりは、99%のケースに確実に対応できる方法を使う方が好みです。
簡単な紹介
orchestratorはGitHubによって活発にメンテナンスされています。これはGitHubの自動フェイルオーバーを担っています。また、地球上で最大規模のMySQL構成の1つであるBooking.comの自動フェイルオーバー、Vitessの一部であるフェイルオーバーを担っています。まだいくつか公にできる名前がありますが、このIssueをながめてみれば何ユーザーかが商用環境でフェイルオーバーを実行していることがわかるでしょう。orchestratorの別の側面として、Square、Etsy、Sendgrid、Godaddyなどなどの非常に多くの会社がトポロジーの管理および可視化に利用しています。
それでは、Severalninesの投稿の1つ1つに対する所見を見ていきましょう。
フラッピング
orchestratorはアンチフラッピング機構をサポートしています。ひとたびフェイルオーバーがキックされたら事前に設定されたRecoveryPeriodBlockSeconds
の間は同一のクラスターでは自動フェイルオーバーは追加で発生しません。我々は例えばその時間を1時間に設定しています。
また一方で、orchestratorは承認(acknowledgements)もサポートしています。人間(あるいはボット、ついでに言えばAPIアクセスあるいはコマンドラインにて)フェイルオーバーを承認できます。一度フェイルオーバーが承認されれば、ブロックが解除されます。次回以降のフェイルオーバーが必要となるインシデントは自由に進めるようになります。
これに加え、いつでも人間が強制的にフェイルオーバーを発動させることができます(例えば、orchestrator -c graceful-master-takeover
またはorchestrator -c force-master-takeover
コマンドによって)。このケースにおいてはブロックは無視され、orchestratorは直ちにフェイルオーバーの一連の操作を開始します。
トランザクションのロスト
orchestratorはバイナリログのデータを故障したマスターから取得せず、レプリカ群の利用可能なデータのみで動作します。データロスの可能性があります。
注: MHAのようなリレーログの同期に関する取り組みは実施されており、実のところこのうちの大部分が現在orchestratorで利用可能となっています。これはエージェントなしにリモートにSSHしリレーログを同期するものです。追加の情報を得るにはhttps://github.com/github/orchestrator/issues/45をご覧ください。我々は何ヶ月かこの問題に取り組んでみましたが、RBR(ROWベースレプリケーション)でリレーログにアトミック性がないといった問題や危険性を認識しました。我々はこれを一度保留することを決め、私はこの機能をorchestratorで利用しないよう意見を述べています。
準同期におけるトランザクションのロスト
Vitessは準同期フェイルオーバーの仕組みにコントリビュートしました(関連する議論)。準同期をご利用でしょうか?すばらしいことです。フェイルオーバーした場合にロストするデータ量を大幅に削減できるでしょう。フェイルオーバー後の新しい構成はどうなっているでしょうか?復旧時に準同期を再適用しますか?Vitessのコントリビューションではまさにそれを実施しており、新しいレプリカが準同期の役割を担います。
トランザクションのロストにおける「最新のレプリカ」について
このような間違った考えがあります。私が経験してきた中で商用環境において何度となくこれが誤った考えであることが証明されてきています。きっとこれは私が経験したことのない宇宙のどこか他のところで起きているのだと考えています。
この間違った考えによると、「マスターが故障した場合、最新のレプリカを昇格させます」とあります。最新である、というのはおそらく誤った選択でしょう。最新のレプリカをスキップして破棄したくなるかもしれません。この仮定は間違った考えで、なぜならば我々の商用環境は無菌状態のきれいな状態(sterile)ではないことは何度となくあるからです。
次のケースを考えてみてください:
- MySQL5.6を運用しておりMySQL 5.7へのアップグレードを試してみたいと考えています。おそらくレプリカの1つあるいは2つをアップグレードし、レプリケーションの性能や、クエリーの遅延などを計測することでしょう。このときsterileではないトポロジーとなります。マスターが故障した場合、決してMySQL 5.7のレプリカを昇格させてはなりません、なぜならばMySQL 5.7から残りのMySQL 5.6にレプリケーションできない(あるいはしようと思わない)からです。
- 我々は5.7のアップグレードは現在2, 3ヶ月間検証しています。私が知っている最も注意が必要な環境ではこのようなアップグレードを実施するのに数ヶ月かけています。トポロジーがsterileではない状態に数ヶ月なるわけです。
- こうして、10のレプリカを破棄するよりかは最新のレプリカを破棄したくなるわけです。
- 同じようにして、もしSTATEMENTベースレプリケーションで運用していたとしましょう。おそらく、ROWベースレプリケーションを試してみたくなることでしょう。このときトポロジーはsterileではありません。残りのレプリカ(log_slave_updatesが有効である想定)へレプリケーションできなくなるため、ROWベースレプリケーションのレプリカを決して昇格させてはいけません
- orchestratorは上記のすべての状況を理解し、正しい動作をします。データのロストを防ぐことより、レプリカ群が生き残ることを確実にすることを優先してレプリカ昇格を実施します。
- レプリケーションフィルターを適用した特別なレプリカがあるとしましょう。予想しているよりも遥かに、これは実際におこっているものです。いくつかのテーブルを機能的に分離するために、新しいサブクラスター分割をしているかもしれません。あるいは、Hadoopへのエクスポートをしていて、特定のイベントにフィルターをかけているかもしれません。あるいは...このレプリカを昇格させてはなりません。
- orchestratorはこのレプリカを昇格させません。
ちょっとおかしなケースについて見てみましょう:
- MySQL 5.7へのアップグレードに話を戻し、10台のうち、8台をMySQL 5.7にアップグレード完了しているとしましょう。現在時点ではMySQL 5.7をきっと昇格させたいでしょう。これはある1台を昇格させたときに他の1台を昇格したさせてときに比べて、何台のレプリカを失うかの問題です。
- orchestratorはこの計算をします。STATEMENTベースとROWベースのレプリカが混在する場合についても同じことがいえます。あるいは5.7とRBRの検証を同時に(チッチッチ、人生は困難なものです)実施しているかもしれません。orchestratorはこのケースでもなお昇格したときにレプリカ群が最も多く無傷で残るようにレプリカを選択します。
- 大多数の最新のレプリカが異なるデータセンターにある
- orchestratorは可能ではありますが昇格しないようにします。とはいうものの一方では、2段階昇格もサポートしています。もし可能であれば、まず最初に異なるデータセンターの最新のレプリカを昇格させ、ローカルデータセンターのレプリカにキャッチアップさせ、それからレプリケーションを逆転させ、ローカルデータセンターのレプリカを最上位に配置し、再度ローカルデータセンタ上でマスターになるようにします。
これがどれだけ有用で重要かはいくら強調してもし足りません。
これはとても都合よく我々を...
ロール
誤った考え: ホワイトリストあるいはブラックリストのサーバー一覧の設定を利用する
上記のMySQL 5.7あるいはROWなどの問題を注意深くブラックリストとしてサーバーにマークを付けることで克服することを期待されることでしょう。
我々もそうしてきました。10サーバーまでの構成であればこれは機能します。これはスケールしません。
再度、明確にしたいのですがこの方法でうまくいくのであれば、それはすばらしいことです!この章の残りの部分を読み飛ばしてください。規模が大きくなれば、これはますます難しい問題となります。100サーバーの規模になれば、これは深刻な悩みの種です。例えば、
set global binlog_format='ROW'
を設定したとしましょう。サーバーのブラックリストを更新するためにすぐにHAサービスを再設定しますか?- 新しいサーバーを準備したとしましょう。追加したサーバーをホワイトリストに加え、HAサービスを再設定する必要がありますか?
- サーバーにメンテナンスが必要だとしましょう。HAサービスの再設定を急いでしますか?
サーバーの自動再設定には投資できるでしょう。私もある程度そうしてきました。これは難しい課題なのです。
- あなたはおそらくホストにタグを割り当てるためにサービスディスカバリーを利用するでしょう。
- それからpuppetが設定を配布するでしょう。
- どのぐらいの速度でできるでしょうか?
- 私は分かっていないのですがここで述べたいずれかの解決策がconsulによって再構成できるかどうかを知りたいです。これはご自分で実施頂く必要があります。
ツールがどれだけ柔軟かも考慮しなくてはなりません。再設定することを想定したときに、あなたのツールが新しい設定を適用しリロードするのがどれだけ容易か、です。
- orchestratorはこれに対して最善を尽くしており、いくつか「read-only」の変数があるものの、ほとんどの設定をオンラインでリロードできます。
HAサービスをどのくらい簡単に再起動できますか?HAが稼働中である任意のタイミングで、ローリングで再起動できるでしょうか?
- orchestratorではこれもよくサポートしています。
orchestratorはこれらのおかしな5.7、ROW、レプリケーションフィルターありのトポロジを魔法のように認識します。いえ、魔法ではありません。これはトポロジーの状態を観測しているにすぎません。クラッシュした時にすべての情報を保持できるようにトポロジーの状態を学んでいます。レプリケーションのルールを知り理解し、データセンターと設定を考慮に入れて良さそうな昇格パスを計算します。
最初は、orchestratorはブラックリストが設定された状態で起動します。これは現在でもなおサポートされます。しかし、今日ではラベルの詳細情報となります。
- レプリカのうちの1台がバックアップサーバーだとします。このサーバーは追加のタスクを実行しており、あるいは異なる設定で(log_slave_updatesが無効?バッファープールの設定が違う?)、マスターとしてはよくありません。そのレプリカを昇格すべきではありません。
「このサーバーはバックアップサーバーで昇格させてはいけない」とある設定で伝える代わりに(これは可能です)、orchestratorではこのサーバーが昇格すべきではないことを動的にアナウンスできます。例えば、10分前はバックアップサーバーではなかったものが、現在はその役割であるといった場合です。orchestratorにこの事実を伝えることができ、次のように実施します。
orchestrator -c register-candidate -i {::fqdn} --promotion-rule=${promotion_rule}
${promotion_rule}にはcandidate、neutralあるいはmust_notが入ります。我々はこれを2, 3分毎にcronでこれを実行しています。我々は、正しいルールを選択するためにサービスディスカバリーを利用しています。orchestratorは役割の変化がある最悪の場合にも常に最新(少なくとも2, 3分前の状態)です(そして緊急のロールの変更は即時に伝播されます)。
また、それぞれのホストは、orchestratorがdiscoverでロールを確認できるように各自のロールを自身で宣言することが可能です(DetectPromotionRuleQuery
)。VItessはこのアプローチを利用していることが知られており、このコードをコントリビュートしました。
ネットワーク分断
まず最初に、通常の故障検知についてです。
orchestratorは故障検知に全体的にみるアプローチをとっていて、これが本当に良い方法であることを説明する代わりに、実際に見せてみたいと思います。orchestratorはフェイルオーバーシナリオを高精度で認識します。Booking.comの商用環境には数千台のMySQLサーバーがあります。この規模では何かが常に故障していますので、サーバーとネットワークはよく故障します。Booking.comのSimon J. Mudd氏の言葉を引用(了承済み)すると
我々は1日に1回は故障があり自動的に処理されています。これは本当に整っていて、マスターが故障することを気にすることはありません。
orchestratorはマスターだけではなく、レプリカも見ています。orchestratorがマスターを観測できず、一方でレプリカが正常に動作しレプリケーションされていれば、orchestratorだけがマスターを参照できないことになります。しかし、orchestratorがマスターを確認できず、かつ全てのレプリカが異常ならば、フェイルオーバーをする必要があります。
ClusterControlでは、誤判定の危険性があるように思われます。: 「...したがってマスターとClusterControlホストの間にネットワークの問題が発生すればfailoverを実施することができます」とあります。
フェンシングに関して:
MHAは故障を検知するのに複数ノードを利用しています。とりわけ、ノード群が異なるデータセンタで稼働しているとき、フェンシングが作用したときにMHAによりよい情報を提供できます。
昨年の9月、Percona Live Amsterdomでの即席の討論セッションで集まりました。我々はフェンシングが作用した際の故障を検知について議論しました。
我々は、例えば3つの異なるデータセンタに3つの監視ノードを設け、そのうちのクォーラムで故障かどうか判断するといった、主に複数の観測ノードを持つことに落ち着きました。
この問題は困難です。マスターが2ノードから監視されており、全てのレプリカ群が故障していた場合、故障でとみなしその際のシナリオを実行すべきでしょうか?2, 3のレプリカが正常で残りの10が正常でない場合はどうでしょうか?
orchestratorでは、クォーラムに基づいてフェイルオーバー検知させる機能がロードマップにのっています。私の見積もりではこれはほとんどの場合正しい動作をしますが、99.99%の正確性となるのはとても難しいことだろうと思います。
インテグレーション
orchestratorはコマンドラインインターフェースに加え、HTTP APIを提供しています。我々はこれをGitHubで利用しており、例えばChatOpsへのorchestratorの組み入れに利用しています。チャット経由でorchestratorに命令をし、情報の取得もまたチャット経由で行います。
また、我々や他の方々はトポロジー再構成をorchestratorのcliを利用し定期ジョブとして自動化しています。
orchestratorとその他のツールの直接的なインテグレーションはありません。最近ではProxySQLとorchestratorを合わせて使えるようにする要望があります。これには様々なユースケースがあると考えています。来るべきPercona Live conference in Santa ClaraでRené Cannaòと私でProxySQLとorchestratorのインテグレーションの可能性についてセッションで共同で発表を行います。オープンディスカッションをする予定です。参加してあなたの考えを教えて下さい!(まだスケジュールされてませんが、スケジューリングされたらこの投稿にリンクを更新します)
マスター/レプリカのロールのインジケーターとしてread_onlyを追加する問題については、https://github.com/sysown/proxysql/issues/789のディスカッションをご覧ください。参考ですが、これは自明なことではなく、内容が信頼出来ないことも多々あるでしょう。あるケースにおいては動作すると思います。
結論
もう時間ですか?まだいいたいことがたくさんありまが、Serveralninesのブログに焦点を当ててみましょう。「結論」の章の比較図についてです。
レプリケーションのサポート
orchestratorは次のフェイルオーバーをサポートしています。
- Oracle GTID
- MariaDB GTID
- Pseudo-GTID
- 準同期
- Binlogサーバー
GTIDのサポートは進めているところです(最近の例)。伝統的にはorchestratorはPseudo-GTIDに焦点をあててきました。
追記します。Pseudo-GTIDは重要です。これはとても、とても良く動作します。Pseudo-GTIDは実際のGTIDを利用し、GTIDの制限事項を受けることなく、全てのOracle GTIDの恩恵を受けられます。明確にある否定的な側面としては、Pseudo-GTIDにもそれ自体の制限事項があります。Pseudo-GTIDの話は別の機会にとっておきますが、GitHubとBooking.comはPseudo-GTIDを元に自動フェイルオーバーを稼働させていることだけは述べておきます。
フラッピング
クラスター毎の時間ベースのブロックおよび、承認(acknowledgements)がサポートされています。人間がこれをオーバーライドすることができます。
トランザクションのロスト
マスターのトランザクションは一切チェックしません。
ネットワーク分断
誤検出の検知にとても優れています。MRMやClusterControlといった他のツールに追随しorchestratorのアプローチで導入されているようであり、これは嬉しいことだと思っています。
ロール
ステートベースの自動検知および意思決定ができます。広告による動的なロール機能もあります。自身でのロールの宣言もサポートします。ブラックリストベースの設定もサポートします。
インテグレーション
HTTP API、コマンドラインインターフェースがあります。他の製品との直接的なインテグレーションはありません。何の約束もしませんがProxySQLとのインテグレーションを検討中です。
追伸
non-GTIDレプリケーションを利用しているならば、MHA一択です。
これは正しくありません。orchestratorは私のバイアスの掛かった意見においては素晴らしい選択肢です。GitHubとBooking.comはいずれもGTIDを利用することなくorchestratorでフェイルオーバーを自動化して運用しています。
ClusterControlだけが... ひとつのツールで両タイプのGTIDを扱うのに十分な柔軟性があります。
これも正しくありません。orchestratorは両タイプのGTIDをサポートしています。私はOracle GTIDをよりうまくサポートできるように取り組んでいます。
...(様々な構成が)混在する環境で1つのツールでレプリケーションの構成で高可用を維持したい場合とても便利なツールです
印象をお伝えさせてください: orchestratorはOracleとMariaDBのサーバー、通常のレプリケーションとbinlogサーバー、STATEMENTおよびROWベースレプリケーション、 同一クラスター内の3メジャーバージョンの混在(思い出して確認したところ、現在この構成で運用していません)トポロジー、および上記の組み合わせた場合に動作します。本当に。
終わりに
あなたに一番あったツールをご利用ください。
おっと、忘れてました!
私が公演するPractical Orchestratorへの参加をご検討ください。ここではorchestratorの構築を1ステップずつご説明し、実際に役立つアドバイスを共有する予定です。