6

Ubuntu で実行されています。プログラムは C++ です。1 つがマスターで、もう 1 つがスレーブの場合、異なるホストで 2 つのプロセスを実行しています (それらの間に優先順位はありません。1 つのみが要求を処理します)。1 つのプロセスのみがマスターになり、要求を処理できます。2 つのプロセスは常に起動しており、クラッシュした場合に備えて、それらを再起動するウォッチドッグがあります。

ホストはネットワーク ケーブルで接続されています。

私の計画は、あるものから別のものへのキープアライブを要求することです。スレーブがマスターからのキープアライブを停止した場合、その状態をマスターに変更する必要があります。マスターが再起動すると、最初にキープアライブを待機し、取得できない場合にマスターとしての役割を設定します。取得した場合は、役割をスレーブとして設定します。

以下についてご意見をお聞かせいただければ幸いです。

両方が同時にマスターになるのを防ぐ方法は? これは私の主な関心事です。起動時と接続障害時に、同時に 2 つのマスターを防止するにはどうすればよいですか?

キープアライブを問い合わせるか、キープアライブを送信した方が良いと思いますか? (私の意見では、プッシュするよりもキープアライブを要求する方が良い)

他の良いアドバイスや落とし穴は大歓迎です。

4

2 に答える 2

4

私がこれを行った方法は、各プロセスが 1 秒に 1 回 UDP パケットを送信するハートビート スレッドを生成し、他のプロセスからの着信 UDP パケットをリッスンすることです。ハートビート スレッドが指定された時間 (たとえば 5 秒間) 他のプロセスから UDP パケットを受信しない場合、他のプロセスがダウンしていると見なし、親スレッドに今すぐマスターになる必要があることを通知します。

ハートビートの送信/リッスンが専用スレッドで行われる理由は、メイン スレッドが長時間の計算でビジー状態になった場合に、ハートビート UDP パケットが一時的に送信されなくなることがないためです。そうすることで、偽のフェイルオーバーのトリガーを回避するために、メイン スレッドのアルゴリズムがリアルタイムである必要がなくなります。

ここで考えなければならない問題がもう 1 つあります。ネットワークの問題によって 2 つのホスト間の通信が一時的に切断された場合はどうなるでしょうか。(たとえば、一部のジョーカーまたは QA テスターは、イーサネット ケーブルを 1 分間取り外してから再度接続します) その場合、両方のプロセスが他のプロセスからの UDP パケットの受信を停止するため、両方のプロセスは、他のプロセスがなくなったと認識し、両方がマスター プロセスになります。その後、ネットワーク ケーブルが再接続されると、2 つのマスター プロセスが同時に実行されますが、これは望ましくありません。したがって、ハイランダーの原則 (「存在できるのは 1 つだけです!」) を満たすために、2 つのマスター プロセスのどちらをスレーブ ステータスに降格させるかを決定する何らかの方法が必要です。これは、「最小の IP アドレスを持つホストをマスターのままにする」という単純なことです。

于 2012-09-22T16:12:08.087 に答える
1

この問題を解決する典型的な方法は、選挙を行うことです。システム内の全員が、アルゴリズムへの入力として使用するデータを共有するため、全員が同じ結論に達することができます。

例:すべてのピア(両方)が相互に一意の識別子(MACアドレス、pid、または高精度のプロセス開始時刻など)を送信します。次に、各ピアは同じ比較を使用して勝者を決定します(最大値など)。次に、結果を互いに通知します。

一時的な接続障害に関する問題については、ビザンチン将軍を参照してください。

参照:

于 2012-09-23T05:21:05.123 に答える