GitHub はどのようにして MySQL の高可用性を実現していますか?次の記事で皆さんと共有しますので、皆さんのお役に立てれば幸いです。
Github は、git
以外のすべてのトランザクションのデータ ストアとして MySQL データベースを使用します。データベースの可用性は、Github が適切に機能するために重要です。 Github Web サイト自体、Github API、認証サービスなどはすべてデータベースにアクセスする必要があります。 Github は、さまざまなサービス タスクをサポートするために複数のデータベース クラスターを実行します。データベース アーキテクチャは従来のマスター/スレーブ構造を採用しており、クラスター内の 1 つのノード (マスター データベース) は書き込みアクセスをサポートし、残りのノード (スレーブ データベース) はマスター データベースへの変更を同期し、読み取りサービスをサポートします。
メイン ライブラリが利用できるかどうかは非常に重要です。メイン データベースがダウンすると、クラスターはデータ書き込みサービスをサポートできなくなります。保存する必要があるデータをデータベースに書き込んで保存することができなくなります。その結果、コードの送信、質問、ユーザー作成、コードレビュー、ウェアハウスの作成など、Github での変更を完了できなくなります。
ビジネスの正常な動作を保証するには、当然のことながら、クラスター内に書き込みをサポートする利用可能なデータベース ノードが必要です。同時に、利用可能な書き込み可能なサービス データベース ノードを迅速に検出できなければなりません。
つまり、異常な状況下でメイン データベースがダウンした場合、新しいメイン データベースが直ちにオンラインになってサービスをサポートできることを確認すると同時に、クラスター内の他のノードが確実にオンラインになるようにする必要があります。新しいメインデータベースをすぐに識別できます。障害検出、マスター移行、およびクラスター内のその他のデータ ノードが新しいマスターを識別するための合計時間は、サービス中断の合計時間になります。
この記事では、GitHub の MySQL 高可用性およびマスター サービス ディスカバリ ソリューションについて説明します。これにより、データ センター間で確実に運用を実行し、データ センターの分離に耐え、障害発生時のダウンタイムにかかる時間を短縮できます。
#この記事で説明するソリューションは、以前の Github 高可用性ソリューションの改良版です。前述したように、MySQL の高可用性戦略はビジネスの変化に適応する必要があります。私たちは、MySQL や GitHub 上のその他のサービスには、変化に対応できる可用性の高いソリューションが備わっていることを期待しています。
高可用性およびサービス検出システム ソリューションを設計する場合、次の質問から始めると、適切なソリューションをすぐに見つけることができます。
上記の問題を説明するために、まず以前の高可用性ソリューションとそれを改善したい理由を見てみましょう。
mysql-writer-1.github.net などのノード名をマスターの仮想 IP アドレス (VIP) に解析して、マスター ノードを見つけます。ノード。
orchestrator は異常を検出し、新しいマスター データベースを選択し、データベース名と仮想 IP (VIP) を再割り当てします。クライアント自体はメイン ライブラリの変更を知りません。クライアントが持つ情報はメイン ライブラリの
name のみであるため、この名前は新しいメイン ライブラリ サーバーに解決できる必要があります。次の点を考慮してください:
実際に VIP を設定すると、VIP は実際の物理的な場所にも影響されます。これは主に、スイッチまたはルーターが配置されている場所によって異なります。したがって、同じローカル サーバー上でのみ VIP を再割り当てできます。特に、他のデータセンターのサーバーに VIP を割り当てることができず、DNS の変更が必要になる場合があります。
これらの制限だけでも、新しいソリューションを見つけるのに十分ですが、次の点を考慮する必要があります:
マスター サーバーの使用法pt- heartbeat
サービスは、 遅延測定とスロットリング制御 を目的として、アクセス ハートビートを挿入します。サービスは新しいプライマリ サーバーで開始する必要があります。可能であれば、プライマリ サーバーを交換するときに、古いプライマリ サーバーのサービスはシャットダウンされます。
同様に、Pseudo-GTID はサーバー自体によって管理されます。新しいマスターで開始する必要があり、できれば古いマスターで停止する必要があります。
新しいマスターは書き込み可能に設定されます。可能であれば、古いマスターは read_only
(読み取り専用) に設定されます。
これらの追加の手順は合計ダウンタイムの要因となり、独自の不具合や摩擦が発生します。
ソリューションは機能し、GitHub は MySQL を正常にフェイルオーバーしましたが、次の領域で HA を改善してほしいと考えています:
新しい戦略により、上記の問題を改善、解決、最適化できます。現在の高可用性コンポーネントは次のとおりです。
anycast
です。 #新しい構造では、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 マスター ノードにつながります。
fqdn、ポート、ipv4、ipv6 を示す KV エントリのセットがあります。
consul-template を実行します。これは、Consul データの変更 (この例では、クラスター マスター データの変更) をリッスンするサービスです。 consul-template 有効な構成ファイルを生成し、構成が変更されたときに HAProxy をリロードする機能を生成します。
orchestrator/raft セットアップを実行します:
orchestrator ノードは
raft## をパスします。 # メカニズムは相互に通信します。各データセンターには 1 つまたは 2 つの orchestrator ノードがあります。
は障害検出と MySQL フェイルオーバーを担当し、master
から Consul に変更を伝達します。フェイルオーバーは単一の orchestrator/raft リーダー ノードによって操作されますが、クラスターに新しい master
が追加されたというメッセージは、## 経由ですべての orchestrator に伝播されます。 #raft メカニズム ノード。
orchestrator
master 変更のメッセージを受信すると、それぞれがローカルの
Consul 設定と通信します。つまり、それぞれが KV write を呼び出します。複数の orchestrator エージェントを持つ DC は、Consul に複数回 (同一の) 書き込みを行います。
プロセスの結合
orchestrator/raft
orchestrator/raft サブクラスター ノードがマスターを変更したことを発表します。
各
orchestrator/raft KV ストアに更新します。
各 GLB/HAProxy は
consul-template KV ストアの変更を監視し、HAProxy を再構成してリロードします。
クライアント トラフィックは新しいマスターにリダイレクトされます。
領事 メッセージの出所を知る必要はありません。エージェントは
Consul のことだけを気にします。クライアントはプロキシのみを気にします。
追加:
伝播される DNS 変更はありません
hard-stop-after
で構成されています。ライター プール内の新しいバックエンド サーバーをリロードすると、古いマスター サーバーへの既存の接続がすべて自動的に終了します。 を使用すると、お客様の協力も必要なくなり、スプリットブレインの状況が軽減されます。これは閉じられておらず、古い接続を終了するまでに
しばらく時間が経過することに注意してください。しかし、ある時点を過ぎると、私たちは快適になり、不快な驚きを期待しなくなります。
は 総合的なアプローチ
を使用して障害を検出するため、非常に信頼性が高くなります。誤検知は観察されませんでした。早期のフェイルオーバーがなかったため、不必要なダウンタイムが発生することはありませんでした。
完全な DC ネットワーク分離 (別名 DC フェンシング) のケースをさらに扱います。 DC ネットワークの分離は混乱を引き起こす可能性があります。DC 内のサーバーは相互に通信できます。 彼らは
他の DC ネットワークから隔離されていますか? それとも 他の DC はネットワークから隔離されていますか? オーケストレーター/raft
raft リーダー ノードがフェイルオーバーを実行するノードです。リーダーは、グループ (定足数) の大多数の支持を得ているノードです。当社のコーディネーター ノードの展開では、1 つのデータ センターが過半数を占めることはなく、n-1 個のデータ センターがあれば十分です。
DC ネットワークが完全に分離されると、DC 内の
orchestrator
orchestrator ノードは、
raft クラスターのリーダーになることはできません。そのようなノードがたまたまリーダーである場合、そのノードは降格します。新しいリーダーは他の DC から割り当てられます。このリーダーは、相互に通信できる他のすべての DC によってサポートされます。
したがって、命令を与える
orchestrator
orchestrator はフェイルオーバーを開始し、使用可能な DC の 1 つのサーバーと置き換えます。分離されていない DC のクォーラムに決定を委任することで、DC の分離を軽減します。
広告の高速化
はフェイルオーバーを開始すると、昇格に使用できるサーバーのキューを監視します。レプリケーション ルールを理解し、ヒントと制限事項を遵守することで、最善の行動方針について知識に基づいた決定を下すことができます。
プロモーションに使用できるサーバーも理想的な候補であると認識される場合があります。例:
準同期レプリケーション
MySQL の
準同期レプリケーション一貫性には、可用性のリスクというコストが伴います。レプリカが変更の受信を確認しない場合、マスターは書き込みをブロックして停止します。幸いなことに、タイムアウト設定があり、その後マスターは非同期レプリケーション モードに戻り、再び書き込みが可能になります。
タイムアウトを適度に低い値 500ms
に設定しました。変更内容はマスター DC レプリカからローカル DC レプリカに送信し、さらにリモート DC にも送信するだけで十分です。このタイムアウトを使用すると、完全な半同期動作 (非同期レプリケーションへのフォールバックなし) を観察でき、確認応答が失敗した場合に非常に短いブロック期間を簡単に使用できます。
ローカル DC レプリカで半同期を有効にし、マスターが停止した場合には、ロスレス フェールオーバーが期待されます (ただし、厳密には強制されません)。完全な DC 障害のロスレス フェイルオーバーは高価であり、期待していません。
半同期タイムアウトを実験しているときに、有利に働く動作も観察しました。一次障害の場合、理想的な候補のアイデンティティに影響を与えることができました。指定したサーバーで半同期を有効にし、候補サーバーとしてマークすることで、障害の結果に影響を与え、全体的なダウンタイムを短縮できます。私たちの 実験 では、すぐに広告を掲載できる 理想的な候補者 が得られることが多いことが観察されました。
アップグレード/ダウングレードされたホスト上の pt-heart
サービスの起動/シャットダウンは管理しませんが、いつでもどこでも実行できます。これには、サーバーが read_only (読み取り専用ステータス) に切り替わったり、完全にクラッシュしたりする状況に pt-heart が適応できるようにするために、いくつかの パッチ
が必要です。
現在の設定では、pt-heart
サービスはマスターとレプリカで実行されます。ホスト上でハートビート イベントを生成します。レプリカでは、サーバーを read_only
(読み取り専用) として識別し、定期的にステータスを再チェックします。サーバーがマスターに昇格すると、そのサーバーの pt-heart
はサーバーが書き込み可能であることを識別し、ハートビート イベントの挿入を開始します。
オーケストレーターをさらに進めます:
read_only
に設定します。 これにより、すべての新しいマスター上の摩擦が軽減されます。新しく昇格したマスターは明らかに生きていて受け入れられるべきです。そうでない場合は昇格しません。したがって、ブーストに適用される msater の変更について オーケストレーター
に直接話させるのが合理的です。
オーケストレーターをさらに強化します:
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 サイトの他の関連記事を参照してください。