HA クラスターでのスプリット ブレインを防ぐ方法
1. はじめに
スプリット ブレインとは、高可用性 (HA) システムにおいて、接続されている 2 つのノードが切断されると、システム全体が 2 つのノードに分割されることを指します。 2 つの独立したノード この時点で、2 つのノードが共有リソースをめぐって競合し始め、システムの混乱とデータの破損が発生します。
ステートレス サービスの HA の場合、スプリット ブレインかどうかは関係ありませんが、ステートフル サービス (MySQL など) の HA の場合は、スプリット ブレインを厳密に防止する必要があります。 (ただし、運用環境の一部のシステムでは、ステートレス サービス HA セットに従ってステートフル サービスが構成されており、その結果は想像できます...)
2. HA クラスターのスプリット ブレインを防ぐ方法
一般的に 2 つの方法を使用します
1. アービトレーション
2 つのノードが同意しない場合、サードパーティのアービターがどちらの決定を聞くかを決定します。このアービターは、ロック サービス、共有ディスク、またはその他のものである可能性があります。
2. フェンシング
ノードのステータスが判断できない場合は、フェンシングによって他のノードを強制終了し、共有リソースが完全に解放されるようにします。その前提として、信頼できるフェンス設備が必要です。
理想的には、上記のどちらも欠けてはいけません。
ただし、ノードがマスター/スレーブ レプリケーションに基づくデータベース HA などの共有リソースを使用しない場合は、フェンス デバイスを安全に省略して、クォーラムのみを保持することもできます。また、多くの場合、クラウド ホストなどの環境では利用可能なフェンス デバイスがありません。
それでは調停を省略してフェンス装置だけを維持してもいいでしょうか?
いいえ。 2 つのノードが相互に接続できなくなると、同時にお互いをフェンシングすることになるためです。フェンシング方法が再起動の場合、2 台のマシンは継続的に再起動します。フェンシング方法の電源がオフの場合、結果として 2 つのノードが一緒に停止するか、1 つが生き残る可能性があります。しかし、2 つのノードが相互に接続できなくなった理由が、一方のノードのネットワーク カード障害であり、生き残ったノードがたまたま障害のあるノードだった場合、結末は悲劇的になります。
つまり、単純な二重ノードでは、いずれにしてもスプリットブレインを防ぐことはできません。
3. フェンスがなくてもデバイスは安全ですか? この問題を説明するために、PostgreSQL または MySQL のデータ レプリケーションを例に挙げます。
レプリケーション ベースのシナリオでは、マスター/スレーブ ノードはリソースを共有しないため、両方のノードが稼働していても問題はありません。問題は、クライアントが停止しているはずのノードにアクセスするかどうかです。これには、やはりクライアントのルーティングの問題が関係します。
クライアントのルーティングには、VIP に基づく、プロキシに基づく、DNS に基づく、または単純にクライアントがサーバー アドレスのリストを保持し、マスターとスレーブを独自に決定するなど、いくつかの方法があります。どちらの方法を使用する場合でも、マスター/スレーブが切り替わったときに配線を更新する必要があります。
DNS はクライアントによってキャッシュされる可能性があり、クリアするのが難しいため、DNS に基づくルーティングは信頼できません。
VIP ベースのルーティングには、いくつかの変動要素があります。停止するはずのノードが VIP を削除しない場合、いつでも問題が発生する可能性があります (新しい所有者が arping を通じてすべてのホストの arp キャッシュを更新した場合でも)。 、ノードの場合、ホストの arp の有効期限が切れて arp クエリが送信されると、ip の競合が発生します。したがって、VIP も特別な共有リソースであり、障害が発生したノードから削除する必要があると考えることができます。ピッキング方法としては、障害ノードが通信が途絶えたことを発見した後、ノードが生きていれば自力でピッキングするのが最も簡単です(死んでいる場合はピッキングする必要はありません)。 VIP の抽出を担当するプロセスが機能しない場合はどうすればよいですか?現時点では、信頼できないソフト フェンス デバイス (ssh など) を使用できます。
プロキシが唯一のサービス入口であるため、プロキシベースのルーティングはより信頼性が高くなります。プロキシが 1 か所で更新される限り、クライアントの誤アクセスの問題は発生しませんが、プロキシの高可用性も考慮する必要があります。
サーバーアドレスリストに基づく方法に関しては、クライアントはバックグラウンドサービスを通じてマスターとスレーブを決定する必要があります(PostgreSQL/MySQLセッションが読み取り専用モードであるかどうかなど)。このときマスターが二人いるとクライアントは混乱してしまいます。この問題を防ぐには、元のマスター ノードが接続が失われたことを発見した後、サービスを自ら停止する必要があります。これは、前の VIP の削除と同じです。
そのため、障害ノードによるトラブルを防ぐために、障害ノードは通信が途絶えた後に自らリソースを解放する必要があり、リソースを解放するプロセスの障害に対処するために、ソフトフェンスを追加することができます。この前提の下では、信頼できる物理的なフェンス設備がなくても安全であると考えることができます。
4. マスター/スレーブ切り替え後にデータが失われないことは保証できますか? マスター/スレーブ切り替えとスプリットブレイン後にデータが失われるかどうかは、2 つの異なる問題であると考えられます。また、PostgreSQL または MySQL のデータ レプリケーションを例として説明します。
PostgreSQL の場合、同期ストリーミング レプリケーション用に構成されている場合、ルーティングが正しいかどうかに関係なく、データは失われません。間違ったノードにルーティングされたクライアントはデータをまったく書き込むことができないため、常にスレーブ ノードからのフィードバックを待ちます。マスターだと思っていたスレーブ ノードは当然それを無視します。もちろん、これが常に発生するのは良いことではありませんが、クラスター監視ソフトウェアがルーティング エラーを修正するのに十分な時間が得られます。
MySQL の場合、半同期レプリケーション用に構成されている場合でも、タイムアウトが発生すると、自動的に非同期レプリケーションにダウングレードされる場合があります。 MySQL レプリケーションの低下を防ぐために、rpl_semi_sync_master_wait_no_slave をオン (デフォルト値) に保ちながら、非常に大きな rpl_semi_sync_master_timeout を設定できます。ただし、このときスレーブに障害が発生するとマスターも停止します。この問題の解決策は PostgreSQL と同じで、1 つのマスターと 2 つのスレーブを構成する (両方のスレーブがダウンしていない限り問題ありません) か、外部クラスター監視ソフトウェアを使用して半同期と非同期を動的に切り替えるかのいずれかです。
非同期レプリケーションが設定されている場合は、データを失う可能性があることを意味します。現時点では、マスターとスレーブを切り替えるときに一部のデータが失われることは大きな問題ではありませんが、自動切り替えの数を制御する必要があります。たとえば、制御がフェイルオーバーされた元のマスターは自動的にオンラインになることはできません。そうしないと、ネットワークのジッターによりフェイルオーバーが発生すると、マスターとスレーブが切り替わり続け、データが失われ、データの一貫性が失われます。
5. 上記の戦略を実装する方法
上記のロジックに準拠する一連のスクリプトを最初から実装できます。ただし、私は、Pacemaker + Corosync + 適切なリソース エージェントなど、成熟したクラスター ソフトウェアに基づいて構築することを好みます。 Keepalived は、ステートフル サービスの HA には適していません。ソリューションにアービトレーションやフェンスを追加しても、常に不快に感じます。
Pacemaker+Corosyncソリューションを使用する際の注意事項もあります
1) リソースエージェントの機能と原理を理解する
リソースエージェントの機能と原理を理解することによってのみ、それが適用できるシナリオを知ることができます。たとえば、pgsql のリソース エージェントは比較的完成度が高く、同期および非同期ストリーム レプリケーションをサポートし、2 つを自動的に切り替えることができ、同期レプリケーション中にデータが失われないことを保証できます。ただし、現在の MySQL のリソース エージェントは非常に弱いため、GTID やログ補正がないとデータが失われやすくなります。これを使用せず、MHA を使用し続けることをお勧めします (ただし、MHA を導入する場合はスプリット ブレインに注意してください)。 )。
2) 正当な投票数 (クォーラム) を確保します
クォーラムは、クラスター内のすべてのノードの過半数がコーディネーターを選出し、クラスター内のすべての命令がこのコーディネーターによって発行されます。スプリットブレイン問題を完全に防ぎます。このメカニズムが効果的に機能するには、クラスター内に少なくとも 3 つのノードが必要であり、no-quorum-policy が stop に設定されており、これがデフォルト値でもあります。 (多くのチュートリアルでは、デモンストレーションの便宜上、no-quorum-policy を無視するように設定しています。他の調停メカニズムを使用せずに運用環境で同じことを行うと、非常に危険です!)
しかし、ノードが 2 つしかない場合はどうなるでしょうか?
1 つ目は、マシンを借りて 3 つのノードを集め、そのノードにリソースが割り当てられないように場所の制限を設定します。
2 つ目は、クォーラムを満たさない複数の小さなクラスターをまとめて大規模なクラスターを形成することです。リソース割り当ての場所を制御するために、場所の制限も適用されます。
しかし、多数の 2 ノード クラスターがある場合、その数を構成するほど多くのノードを見つけることができず、これらの 2 ノード クラスターをまとめて大きなクラスターを形成することは望ましくありません (たとえば、管理が不便だと思います)。次に、3 番目の方法を検討できます。
3 番目の方法は、プリエンプトされたリソースと、このプリエンプトされたリソースのサービスとコロケーション制約を設定することです。このプリエンプトされたリソースは、Zookeeper に基づいてパッケージ化されたロック サービスなどのロック サービスにすることも、以下の例のように単純に最初から作成することもできます。
http://my.oschina.net/hanhanztj/blog/515065
(この例は、http プロトコルに基づく短い接続です。より詳細なアプローチは、サーバーが接続を検出できるように、長い接続のハートビート検出を使用することです。ロックを解除してください)
ただし、このプリエンプトされたリソースの高可用性も確保する必要があります。プリエンプトされたリソースを提供するサービスを lingyig 高可用性にすることも、よりシンプルにして 3 つのサービスを 1 つずつデプロイすることもできます。デュアル ノードと 3 番目のノードは別の専用クォーラム ノードにデプロイされ、ロックが取得されたと見なされる前に 3 つのロックのうち少なくとも 2 つが取得されます。このクォーラム ノードは、多くのクラスターにクォーラム サービスを提供できます (マシンは 1 つの Pacemaker インスタンスのみをデプロイできるため、それ以外の場合は、N 個の Pacemaker インスタンスがデプロイされたアービター ノードを使用して同じことを行うことができます)。ただし、そうするしかない場合は、Pacemaker の法定投票数を満たすための以前の方法を使用してみてください。この方法の方が簡単で信頼性が高くなります。
6. 参考資料
http://blog.chinaunix.net/uid-20726500-id-4461367.html
http://my.oschina.net/hanhanztj/blog/515065
http://clusterlabs.org /doc/en-US/Pacemaker/1.1-plugin/html-single/Pacemaker_Explained/index.html
http://clusterlabs.org/wiki/PgSQL_Replicated_Cluster
http://mysqllover.com/?p=799
http: //gmt-24.net/archives/1077
http://www.bkjia.com/PHPjc/1073479.htmlwww.bkjia.com本当http://www.bkjia.com/PHPjc/1073479.html技術記事 HA クラスターでスプリット ブレインを防ぐ方法 1. はじめに スプリット ブレインとは、高可用性 (HA) システムにおいて、接続されている 2 つのノードが切断されると、元々は全体であったシステムが...