Raft(分散合意アルゴリズム)について
クラスタ内の全サーバに一貫性のあるステートマシンを提供するためのアルゴリズム(?):
イメージ図 (見返してみると、論文のFigure1とかなり似ていた...):
実用的な分散合意アルゴリズムは典型的には以下の性質を備えている(らしい):
論文では、Paxosは難しすぎる、というのが前提としてある:
Raftは理解可能性を最重視:
投票要求RPC(RequestVote)
とログエントリ追加RPC(AppendEntries)
若干不正確かもしれないですが、一応必要最低限の用語定義:
{インデックス、term}
のペアで、ログのエントリを一意に特定するキーとなるログの図(論文のFigure6より):
termの図(論文のFigure5より):
NOTE: 後で再び触れるので、ここは項目名を読むくらいで飛ばす
{インデックス、term}
のペアを保持しているなら、先頭からそのインデックスに至るまでの全てのエントリは等しい以下の三つのサブ問題に分割されている:
補足:
leader
、candidate
、follower
の三つがあるRaftはリーダーに強い役割を割当てることでモデルを単純にしている:
leader => follower
の流れしかない(一方通行)つまり、一度リーダーが選出されると、
基本的には多数決(majority)ルール:
follower
=> candidate
にステートが変わったサーバが選出処理を始める (遷移条件は後述)leader
になるleader
を維持票が割れたらどうするか?
candidate
サーバが同時にRequestVoteRPCをブロードキャストした場合等に発生する可能性あり競合者がいなくてもリジェクトされることがある:
follower
にステートが遷移する(後述)この選出方法は[1] 選出安全性
を保証する:
参考サイト: http://thesecretlivesofdata.com/raft/
follower
、candidate
、leader
のステートがどう遷移するか。
※ 末尾の遷移図を見れば十分
サーバの起動直後はfollower
:
candidate
になる(選出処理の開始)
candidate
サーバは上述の選出処理を行い:
follower
になる。
leader
に選ばれたleader
になるcandidate
のままで(ウェイト後に)リトライするleader
は:
follower
になる
candidate
の時と同様に、自分よりも新しい(時間/termが進んでいる)のサーバがいたら、一度follower
になるleader
状態が維持されるステート遷移の図(論文のFigure4):
可用性をあげるためにはレプリケーションが必要。
ログのサーバ間での一貫性をどう維持するかが問題:
leader
のログがマスターfollower
との間で差異(齟齬)が生じ得る:
leader
がクライアントからのリクエスト(コマンド)を受けて、ログにエントリを追加したfollower
が何らかの理由で(RPC通信に)極端に遅延しているfollower
のダウンからの復帰直後 (起動後はまずストレージに保存されたログを読み込む)leader
になった直後
(a)
と(f)
)leader
に追従)が必要leader
とfollower
で差異が生じる例 (論文のFigure7):
クライアントからのリクエスト(コマンド)をどう処理するか(正常系?):
follower
にブロードキャスト (AppendEntriesRPC)follower
にもコミットを反映)正常系以外は?
follower
のログが先に進みすぎ、後ろ過ぎ
follower
はどうする?
このレプリケーション方法は[2] リーダーは追記のみ
と[3] ログマッチング
を保証する:
{インデックス、term}
のペアを保持しているなら、先頭からそのインデックスに至るまでの全てのエントリは等しい上の二節で取り上げた方法はかなりシンプル and アルゴリズムの外観を掴むには十分。
ただし、
{インデックス, term}
の大小比較もします、という話:
candidate
のログが、他のマジョリティのそれと同じくらい進んでいることを保証したいのでインデックスも加味するコミット破棄の図 (論文のFigure8):
要約:
! 以下の二つが満たされる:
サーバを止めずにクラスタの構成(メンバーリスト)を更新するにはどうすれば良いか?
idempotent
だから大丈夫boardcatTime << electionTimeout << MTBF
が満たせないと可用性が損なわれる
ログの肥大化を防ぐにはどうすれば良いか?
スナップショットを使う:
余裕があれば 9.3 を読んで軽く書く
Raftは実用的な分散合意アルゴリズムが備えるべき性質を保持しているか?
TODO: