4

実装 RAFT について次の質問があります。

次のシナリオ\実装を検討してください。

  1. RAFT リーダーはコマンド エントリを受信し、エントリをメモリ内配列に追加します。次に、エントリをフォロワーに送信します (ハートビートを使用)。
  2. フォロワーはエントリを受信し、それをメモリ内配列に追加してから、エントリを受信したという応答を送信します。
  3. 次に、リーダーはエントリを永続的なストア (ファイル) に書き込むことでコミットします。リーダーは最新のコミット インデックスをハートビートで送信します。
  4. 次にフォロワーは、エントリを永続ストア (ファイル) に保存することにより、リーダーのコミット インデックスに基づいてエントリをコミットします。

RAFT の実装の 1 つ (リンク: https://github.com/peterbourgon/raft/ ) は、このように実装しているようです。これでいいのか確認したかった。

エントリがコミットされるまで、リーダーとフォロワーによって「メモリ内」に維持されていても問題ありませんか? このシナリオはどのような状況で失敗する可能性がありますか?

4

3 に答える 3

3

raft-dev google グループに投稿して、質問に対する答えを見つけました。参考までに回答を追加しました。

参照してください: https://groups.google.com/forum/#!msg/raft-dev/_lav2NeiypQ/1QbUB52fkggJ

ディエゴの答えを引用:

相関する停電が発生した場合でも安全を確保するために、大部分のサーバーは、その影響が外部化される前にログ エントリを永続化する必要があります。過半数に満たない場合、それらのサーバーは永久に失敗し、データの損失/破損が発生する可能性があります

同じことに関する私の電子メールに対するベン・ジョンソンの回答から引用します。

いいえ、サーバーはクォーラムの一部と見なされる前にエントリをディスクにフラッシュする必要があります。

たとえば、A、B、および C という名前のノードのクラスターがあり、A がリーダーであるとします。

  1. ノード A はエントリをノード B に複製します。

  2. ノード B はエントリをメモリに保存し、ノード A に応答します。

  3. ノード A にはクォーラムがあり、エントリをコミットします。

  4. その後、ノード A はノード B と C から分割されます。

  5. その後、ノード B は停止し、メモリ内のエントリのコピーを失います。

  6. ノード B が復旧します。

  7. その後、ノード B と C がリーダーを選出するときに、「コミットされた」エントリはログに記録されません。

  8. ノード A がクラスターに再参加すると、一貫性のないログが作成されます。エントリはコミットされ、ステート マシンに適用されるため、ロールバックできません。

ベン

于 2014-04-29T17:45:27.137 に答える