GitHub が MySQL の可用性を高める方法について話しましょう

青灯夜游
リリース: 2022-11-02 20:18:41
転載
2380 人が閲覧しました

GitHub が MySQL の可用性を高める方法について話しましょう

Github は、git 以外のすべてのトランザクションのデータ ストアとして MySQL データベースを使用します。データベースの可用性は、Github が適切に機能するために重要です。 Github Web サイト自体、Github API、認証サービスなどはすべてデータベースにアクセスする必要があります。 Github は、さまざまなサービス タスクをサポートするために複数のデータベース クラスターを実行します。データベース アーキテクチャは従来のマスター/スレーブ構造を採用しており、クラスター内の 1 つのノード (マスター データベース) は書き込みアクセスをサポートし、残りのノード (スレーブ データベース) はマスター データベースへの変更を同期し、読み取りサービスをサポートします。

メイン ライブラリが利用できるかどうかは非常に重要です。メイン データベースがダウンすると、クラスターはデータ書き込みサービスをサポートできなくなります。保存する必要があるデータをデータベースに書き込んで保存することができなくなります。その結果、コードの送信、質問、ユーザー作成、コードレビュー、ウェアハウスの作成など、Github での変更を完了できなくなります。

ビジネスの正常な動作を保証するには、当然のことながら、クラスター内に書き込みをサポートする利用可能なデータベース ノードが必要です。同時に、利用可能な書き込み可能なサービス データベース ノードを迅速に検出できなければなりません。

つまり、異常な状況下でメイン データベースがダウンした場合、新しいメイン データベースが直ちにオンラインになってサービスをサポートできることを確認すると同時に、クラスター内の他のノードが確実にオンラインになるようにする必要があります。新しいメインデータベースをすぐに識別できます。障害検出、マスター移行、およびクラスター内のその他のデータ ノードが新しいマスターを識別するための合計時間は、サービス中断の合計時間になります。

この記事では、GitHub の MySQL 高可用性およびマスター サービス ディスカバリ ソリューションについて説明します。これにより、データ センター間で確実に運用を実行し、データ センターの分離に耐え、障害発生時のダウンタイムにかかる時間を短縮できます。

高可用性の実装

この記事で説明するソリューションは、以前の Github 高可用性ソリューションの改良版です。前述したように、MySQL の高可用性戦略はビジネスの変化に適応する必要があります。私たちは、MySQL や GitHub 上のその他のサービスには、変化に対応できる可用性の高いソリューションが備わっていることを期待しています。

高可用性およびサービス検出システム ソリューションを設計する場合、次の質問から始めると、適切なソリューションをすぐに見つけることができます。

  • 許容される最大サービス中断時間は何時ですか?
  • サービス中断の検出はどの程度正確ですか?サービス停止検出で誤検知 (早期フェイルオーバーを引き起こす) を検出できますか?
  • フェイルオーバーの信頼性はどの程度ですか?フェイルオーバーが失敗する原因となる条件は何ですか?
  • このソリューションはデータセンター全体に実装できますか?また、どのように実装されますか?さまざまなネットワーク条件、遅延が大きい場合、または遅延が小さい場合はどうなりますか?
  • このソリューションは、データセンター (DC) 全体の障害やネットワークの分離に耐えることができますか?
  • HA クラスターのスプリット ブレイン状況 (システム全体で、接続された 2 つのノードが 2 つの独立したノードに分割され、2 つのノードがデータを書き込むための共有リソースをめぐって競合する) を防ぐメカニズムはありますか?
  • データ損失は許容できますか?どのレベルの損失が許容されますか?

上記の問題を説明するために、まず以前の高可用性ソリューションとそれを改善したい理由を見てみましょう。

VIP と DNS に基づく検出メカニズムを放棄する

前のソリューションでは、次の技術的ソリューションが適用されました:

  • Useorchestrator 障害検出移行ソリューションとして。
  • VIP および DNS メソッドをマスター ノード検出ソリューションとして使用します。

クライアントは、mysql-writer-1.github.net などのノード名をマスターの仮想 IP アドレス (VIP) に解析して、マスター ノードを見つけます。ノード。

したがって、通常の状況では、クライアントはノード名を解析することで、対応する IP のマスター ノードに接続できます。

3 つのデータ センターのトポロジを考えてみましょう。

GitHub が MySQL の可用性を高める方法について話しましょう

メイン データベースが異常になったら、データ レプリカ サーバーの 1 つをメイン データベース サーバーに更新する必要があります。 。

orchestrator は異常を検出し、新しいマスター データベースを選択し、データベース名と仮想 IP (VIP) を再割り当てします。クライアント自体はメイン ライブラリの変更を知りません。クライアントが持つ情報はメイン ライブラリの name のみであるため、この名前は新しいメイン ライブラリ サーバーに解決できる必要があります。次の点を考慮してください:

VIP はネゴシエートする必要があります: 仮想 IP はデータベース自体によって保持されます。サーバーは、VIP を占有または解放するには ARP リクエストを送信する必要があります。新しいデータベースが新しい VIP を割り当てる前に、古いサーバーはまず保持している VIP を解放する必要があります。このプロセスにより、いくつかの異常な問題が発生します:

  • フェイルオーバーのシーケンスは、まず障害が発生したマシンに VIP の解放を要求し、次に新しいメイン データベース マシンに連絡して VIP を割り当てることです。しかし、障害が発生したマシン自体にアクセスできない場合、または VIP の解放を拒否した場合はどうなるでしょうか?マシン障害のシナリオを考慮すると、障害が発生したマシンは VIP の解放要求にすぐに応答しないか、まったく応答しません。プロセス全体には次の 2 つの問題があります:
    • スプリットブレイン状況: 2 つのホストが保持している場合同じ VIP の場合、異なるクライアントは最短のネットワーク リンクに基づいて異なるホストに接続します。
    • VIP の再割り当てプロセス全体は 2 つの独立したサーバーの相互調整に依存しており、セットアップ プロセスは信頼できません。
  • 障害が発生したマシンが VIP を正常に解放したとしても、切り替えプロセスでは障害が発生したマシンへの接続も必要となるため、プロセス全体に非常に時間がかかります。
  • VIP が再割り当てされた場合でも、クライアントの既存の接続は古い障害が発生したマシンから自動的に切断されず、システム全体でスプリット ブレイン状況が発生します。

実際に VIP を設定すると、VIP は実際の物理的な場所にも影響されます。これは主に、スイッチまたはルーターが配置されている場所によって異なります。したがって、同じローカル サーバー上でのみ VIP を再割り当てできます。特に、他のデータセンターのサーバーに VIP を割り当てることができず、DNS の変更が必要になる場合があります。

  • DNS の変更が反映されるまでには時間がかかります。クライアントは、設定された時間で最初に DNS 名をキャッシュします。クロスプラットフォーム フェールオーバーは、より多くの停止を意味します。クライアントは、新しいプライマリ サーバーを認識するためにより多くの時間を費やす必要があります。

これらの制限だけでも、新しいソリューションを見つけるのに十分ですが、次の点を考慮する必要があります:

  • マスター サーバーの使用法pt- heartbeat サービスは、 遅延測定とスロットリング制御 を目的として、アクセス ハートビートを挿入します。サービスは新しいプライマリ サーバーで開始する必要があります。可能であれば、プライマリ サーバーを交換するときに、古いプライマリ サーバーのサービスはシャットダウンされます。

  • 同様に、Pseudo-GTID はサーバー自体によって管理されます。新しいマスターで開始する必要があり、できれば古いマスターで停止する必要があります。

  • 新しいマスターは書き込み可能に設定されます。可能であれば、古いマスターは read_only(読み取り専用) に設定されます。

これらの追加の手順は合計ダウンタイムの要因となり、独自の不具合や摩擦が発生します。

ソリューションは機能し、GitHub は MySQL を正常にフェイルオーバーしましたが、次の領域で HA を改善してほしいと考えています:

  • データ センターに依存しない。
  • データセンターの障害を許容します。
  • 信頼性の低いコラボレーション ワークフローを削除します。
  • 総ダウンタイムを削減します。
  • 可能な限り、ロスレス フェイルオーバーを使用します。

GitHub の高可用性ソリューション: オーケストレーター、Consul、GLB

新しい戦略により、上記の問題を改善、解決、最適化できます。現在の高可用性コンポーネントは次のとおりです。

  • orchestrator 検出とフェイルオーバーを実行します。リンク orchestrator/raft で説明されているように、ハイブリッド データセンターを採用します。
  • Hashicorp の Consul はサービスとして検出されます。
  • GLB/HAProxy クライアントと書き込みノードの間のプロキシとして機能します。 GLB ガイダンスは、ネットワーク ルーターとして オープン ソース.
  • anycast です。

GitHub が MySQL の可用性を高める方法について話しましょう

#新しい構造では、VIP と DNS が削除されます。より多くのコンポーネントを導入すると、それらを分離して関連タスクを簡素化し、信頼性が高く安定したソリューションを活用しやすくなります。詳細は以下の通り。

通常のプロセス

通常、アプリケーションは GLB/HAProxy 経由で書き込みノードに接続します。

アプリケーションはマスター ID を感知できません。以前は名前が使用されていました。たとえば、cluster1 のマスターは mysql-writer-1.github.net です。現在の構造では、この名前は anycast IP に置き換えられます。

anycast では、名前は同じ IP に置き換えられますが、トラフィックはクライアントの場所によってルーティングされます。特に、データセンターに GLB がある場合、高可用性ロード バランサーは別のボックスにデプロイされます。 mysql-writer-1.github.net へのトラフィックは、ローカル データ センターの GLB クラスターに送信されます。このようにして、すべてのクライアントがローカル プロキシによってサービスを受けます。

HAProxy の上で GLB を使用します。 HAProxy には 書き込みプール があり、MySQL クラスターごとに 1 つあります。各プールにはバックエンド サービス、つまりクラスター マスター ノードがあります。データセンター内のすべての GLB/HAProxy ボックスには同じプールがあります。これは、これらのプールが同じバックエンド サービスに対応することを意味します。したがって、アプリケーションが mysql-writer-1.github.net を書き込むことを想定している場合、どの GLB サービスに接続するかは気にしません。これは、実際の cluster1 マスター ノードにつながります。

アプリケーションが GLB に接続されており、検出サービスに関する限り、再検出は必要ありません。 GLB は、すべてのトラフィックを正しい宛先に転送する責任があります。

GLB はどのサービスがバックエンドであるかをどのように認識し、GLB に変更を通知するのでしょうか?

Consul による検出

Consul はサービス検出ソリューションで知られており、DNS サービスも提供しています。ただし、私たちのソリューションでは、これを高可用性の Key-Value (KV) ストアとして使用します。

Consul の KV ストレージに、クラスター マスター ノードの ID を書き込みます。各クラスターには、クラスターのマスター

fqdn、ポート、ipv4、ipv6 を示す KV エントリのセットがあります。

各 GLB/HAProxy ノードは、

consul-template を実行します。これは、Consul データの変更 (この例では、クラスター マスター データの変更) をリッスンするサービスです。 consul-template 有効な構成ファイルを生成し、構成が変更されたときに HAProxy をリロードする機能を生成します。

したがって、各 GLB/HAProxy マシンは、マスター ID に対する Consul の変更を監視し、それから自身を再構成し、クラスター バックエンド プール内の単一のエンティティとして新しいマスターを設定し、これらの変更を反映するためにリロードします。

GitHub では、各データ センターに Consul セットアップがあり、各セットアップの可用性が高くなります。ただし、これらの設定は相互に独立しています。相互にコピーしたり、データを共有したりすることはありません。

Consul は変更についてどのように学習しますか?また、情報は DC 全体にどのように配布されますか?

orchestrator/raft

#orchestrator/raft セットアップを実行します: orchestrator ノードraft メカニズムを通じて相互に通信します。各データセンターには 1 つまたは 2 つの orchestrator ノードがあります。

orchestrator は障害検出と MySQL フェイルオーバーを担当し、master から Consul に変更を伝達します。フェイルオーバーは単一の orchestrator/raft リーダー ノードによって操作されますが、クラスターに新しい master が追加されたというメッセージは、## 経由ですべての orchestrator に伝播されます。 #raft メカニズム ノード。

orchestrator

ノードが master 変更のメッセージを受信すると、それぞれがローカルの Consul 設定と通信します。つまり、それぞれが KV write を呼び出します。複数の orchestrator エージェントを持つ DC は、Consul に複数回 (同一の) 書き込みを行います。

プロセスの結合

マスタークラッシュの場合:

    orchestrator
  • ノード検出失敗。
  • orchestrator/raft
  • リーダー ノードが回復を開始し、データ サーバーがマスターになるように更新されます。
  • orchestrator/raft
  • すべての raft サブクラスター ノードがマスターを変更したことを発表します。
  • orchestrator/raft
  • メンバーは、リーダー ノードの変更の通知を受け取ります。各メンバーは、新しいマスターをローカルの Consul KV ストアに更新します。 各 GLB/HAProxy は
  • consul-template
  • を実行し、Consul KV ストアの変更を監視し、HAProxy を再構成してリロードします。 クライアント トラフィックは新しいマスターにリダイレクトされます。
  • 各コンポーネントには明確な責任があり、設計全体が分離され、簡素化されます。
orchestrator

ロード バランサーについてはわかりません。 領事 メッセージの出所を知る必要はありません。エージェントは Consul のことだけを気にします。クライアントはプロキシのみを気にします。 追加:

伝播される DNS 変更はありません
  • TTL はありません。
  • ストリームは障害が発生したマスターと連携していないため、ほとんど無視されます。
追加の詳細

トラフィックをさらに保護するために、次の機能もあります:

  • HAProxy は非常に短い hard-stop-after で構成されています。ライター プール内の新しいバックエンド サーバーをリロードすると、古いマスター サーバーへの既存の接続がすべて自動的に終了します。
    • ハードストップアフターを使用すると、お客様の協力も必要なくなり、スプリットブレインの状況が軽減されます。これは閉じられておらず、古い接続を終了するまでに しばらく時間が経過することに注意してください。しかし、ある時点を過ぎると、私たちは快適になり、不快な驚きを期待しなくなります。
    領事が常に待機していることを厳密に要求しているわけではありません。実際には、フェイルオーバー時に使用できるようにするだけで十分です。 Consul が失敗した場合、GLB は最後に知られた値を使用して動作し続け、抜本的なアクションは実行しません。
  • GLB は、新しく昇格したマスターの ID を検証するように設定されています。
  • Context-Aware MySQL Pool
  • と同様に、バックエンド サーバー上でチェックが行われ、それが実際にライター ノードであることが確認されます。 Consul でマスターの ID を削除しても問題ありません。空のエントリは無視されます。誤って Consul に非マスター名を書き込んでも問題ありません。GLB はその更新を拒否し、最後に知られた状態で実行を継続します。
  • 次のセクションでは、この問題にさらに取り組み、HA の目標を追求します。

オーケストレーター/RAFT 障害検出

#オーケストレーター

総合的なアプローチを使用して障害を検出する, とても信頼できます。誤検知は観察されませんでした。早期のフェイルオーバーがなかったため、不必要なダウンタイムが発生することはありませんでした。

オーケストレーター/ラフト

完全な DC ネットワーク分離 (別名 DC フェンシング) のケースをさらに扱います。 DC ネットワークの分離は混乱を引き起こす可能性があります。DC 内のサーバーは相互に通信できます。 彼らは 他の DC ネットワークから隔離されていますか? それとも 他の DC はネットワークから隔離されていますか? オーケストレーター/raft

セットアップでは、

raft リーダー ノードがフェイルオーバーを実行するノードです。リーダーは、グループ (定足数) の大多数の支持を得ているノードです。当社のコーディネーター ノードの展開では、1 つのデータ センターが過半数を占めることはなく、n-1 個のデータ センターがあれば十分です。 DC ネットワークが完全に分離されると、DC 内の orchestrator

ノードは他の DC のピアノードから切断されます。したがって、分離された DC 内の

orchestrator ノードは、raft クラスターのリーダーになることはできません。そのようなノードがたまたまリーダーである場合、そのノードは降格します。新しいリーダーは他の DC から割り当てられます。このリーダーは、相互に通信できる他のすべての DC によってサポートされます。 したがって、命令を与える orchestrator

ノードは、ネットワーク分離データ センターの外部のノードになります。スタンドアロン DC にマスターがある場合、

orchestrator はフェイルオーバーを開始し、使用可能な DC の 1 つのサーバーと置き換えます。分離されていない DC のクォーラムに決定を委任することで、DC の分離を軽減します。 広告の高速化

大きな変更をより速く公開することで、合計のダウンタイムをさらに短縮できます。これを達成するにはどうすればよいでしょうか?

オーケストレーター

はフェイルオーバーを開始すると、昇格に使用できるサーバーのキューを監視します。レプリケーション ルールを理解し、ヒントと制限事項を遵守することで、最善の行動方針について知識に基づいた決定を下すことができます。

プロモーションに使用できるサーバーも理想的な候補であると認識される場合があります。例:

サーバーのアップグレードを妨げるものは何もありません (ユーザーがヒントを与えた可能性があります)そのようなサーバーが優先アップグレードであること)、サーバーはその兄弟すべてをレプリカとして持つことができることが期待されます。

    この場合、
  • orchestrator
  • は、レプリケーション ツリーの修復が開始されても、最初にサーバーを書き込み可能にしてから、すぐにサーバーをアドバタイズします (この場合は Consul KV ストアに書き込みます)。非同期では、この操作には通常数秒かかります。
  • GLB サーバーが完全にリロードされる前にレプリケーション ツリーが損なわれない可能性もありますが、厳密に必要というわけではありません。サーバーは書き込みを非常によく受け入れます。

準同期レプリケーション

MySQL の

準同期レプリケーション

では、マスター サーバーは、既知の変更が送信されるまでトランザクションのコミットを確認しません。 1 つ以上のコピー。これにより、ロスレス フェールオーバーを実現する方法が提供されます。プライマリ サーバーに適用された変更はすべて、プライマリ サーバーに適用されるか、レプリカの 1 つに適用されるまで待機します。

一貫性には、可用性のリスクというコストが伴います。レプリカが変更の受信を確認しない場合、マスターは書き込みをブロックして停止します。幸いなことに、タイムアウト設定があり、その後マスターは非同期レプリケーション モードに戻り、再び書き込みが可能になります。

タイムアウトを適度に低い値 500ms に設定しました。変更内容はマスター DC レプリカからローカル DC レプリカに送信し、さらにリモート DC にも送信するだけで十分です。このタイムアウトを使用すると、完全な半同期動作 (非同期レプリケーションへのフォールバックなし) を観察でき、確認応答が失敗した場合に非常に短いブロック期間を簡単に使用できます。

ローカル DC レプリカで半同期を有効にし、マスターが停止した場合には、ロスレス フェールオーバーが期待されます (ただし、厳密には強制されません)。完全な DC 障害のロスレス フェイルオーバーは高価であり、期待していません。

半同期タイムアウトを実験しているときに、有利に働く動作も観察しました。一次障害の場合、理想的な候補のアイデンティティに影響を与えることができました。指定したサーバーで半同期を有効にし、候補サーバーとしてマークすることで、障害の結果に影響を与え、全体的なダウンタイムを短縮できます。私たちの 実験 では、すぐに広告を掲載できる 理想的な候補者 が得られることが多いことが観察されました。

Inject heartbeat

アップグレード/ダウングレードされたホスト上の pt-heart サービスの起動/シャットダウンは管理しませんが、いつでもどこでも実行できます。これには、サーバーが read_only (読み取り専用ステータス) に切り替わったり、完全にクラッシュしたりする状況に pt-heart が適応できるようにするために、いくつかの パッチが必要です。

現在の設定では、pt-heart サービスはマスターとレプリカで実行されます。ホスト上でハートビート イベントを生成します。レプリカでは、サーバーを read_only(読み取り専用) として識別し、定期的にステータスを再チェックします。サーバーがマスターに昇格すると、そのサーバーの pt-heart はサーバーが書き込み可能であることを識別し、ハートビート イベントの挿入を開始します。

オーケストレーター所有権の委任

#さらにオーケストレーター:

  • 疑似 GTID を注入します。
  • 昇格したマスターを書き込み可能に設定し、そのレプリケーション ステータスをクリアして、
  • 可能であれば古いマスターを read_only に設定します。

これにより、すべての新しいマスター上の摩擦が軽減されます。新しく昇格したマスターは明らかに生きていて受け入れられるべきです。そうでない場合は昇格しません。したがって、ブーストに適用される msater の変更について オーケストレーター に直接話させるのが合理的です。

#オーケストレーター所有権の委任

#オーケストレーターをさらに強化します:

    疑似 GTID インジェクション、
  • 昇格したマスターを書き込み可能に設定し、そのレプリケーション ステータスをクリアして、
  • 可能であれば古いマスターを
  • read_only に設定します。
これにより、すべての新しいマスター上の摩擦が軽減されます。新しく昇格したマスターは明らかにライブで受け入れられるものでなければなりません。そうでない場合は昇格しません。したがって、

オーケストレーター が変更を昇格された msater に直接適用するのが合理的です。

制限事項と欠点

プロキシ層は、アプリケーションがプライマリ サーバーの ID を認識しないようにしますが、アプリケーションのプライマリ サーバーの ID もマスクします。主に表示されるのはプロキシ層からの接続だけであり、接続の実際の発信元に関する情報は失われます。

分散システムの発展に伴い、私たちは依然として未処理のシナリオに直面しています。

データセンター分離シナリオでは、プライマリ サーバーが分離された DC に配置されていると仮定すると、DC 内のアプリケーションは引き続きプライマリ サーバーに書き込みできることに注意してください。これにより、ネットワークが復元された後に状態が不安定になる可能性があります。私たちは、非常にサイロ化された DC 内から信頼性の高い

STONITH を実装することで、このスプリット ブレインを軽減することに取り組んでいます。以前と同様に、予備選挙が破壊されるまでにはしばらく時間がかかり、短期間の間、頭脳が分裂する可能性があります。頭脳の分裂を回避するための運用コストは非常に高くなります。

さらに多くのケースがあります: フェイルオーバー時に consul サービスを停止する、部分的な DC 分離、その他のケース。この種の分散システムのすべての脆弱性を埋めるのは不可能であることを私たちは知っているため、最も重要なケースに焦点を当てます。

結論

当社のコーディネーター/GLB/領事から次の情報が提供されました:

  • 信頼性の高い障害検出、
  • データセンターに依存しないフェイルオーバー、
  • 一般にロスレス フェイルオーバー、
  • データセンター ネットワーク分離サポート、
  • 分割の軽減-頭脳 (より多くの作業結果)、
  • 協力に依存しない、
  • ほとんどの場合、合計中断時間は 10 ~ 13 秒 の間です。
    • まれなケースでは、合計ダウンタイムが最大 20 秒、極端な場合には最大 25 秒になる場合があります。

#結論

ビジネス プロセス/プロキシ/サービス検出パラダイムは、分離されたアーキテクチャでよく知られた信頼できるコンポーネントを使用します。導入、運用、観察が容易になり、各コンポーネントを個別にスケールアップまたはスケールダウンできます。私たちは常に設定をテストし、改善点を探すことができます。

元のアドレス: https://github.blog/2018-06-20-mysql-high-availability-at-github/

翻訳アドレス: https://learnku .com/mysql/t/36820

[関連する推奨事項:

mysql ビデオ チュートリアル]

以上がGitHub が MySQL の可用性を高める方法について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:learnku.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート