ZooKeeper 基本の仕組み


ZooKeeper サーバーはどのようにして Leader を決めているのか?

公式ドキュメントによると、アルゴリズムはTCPをベースにしたものがデフォルトになっているらしい。
実際に選出される Leader は特に早いもの勝ちという訳ではなく、ZooKeeper アンサンブルが構築された時点(5台構成なら、3台が起動した時点)でその3台の中からランダムに選出がされている模様。(実際にはここでTCPベースのアルゴリズムに依存しているのかもしれないが)

Election implementation to use. A value of "0" corresponds to the original UDP-based version, "1" corresponds to the non-authenticated UDP-based version of fast leader election, "2" corresponds to the authenticated UDP-based version of fast leader election, and "3" corresponds to TCP-based version of fast leader election. Currently, algorithm 3 is the default
The implementations of leader election 0, 1, and 2 are now deprecated . We have the intention of removing them in the next release, at which point only the FastLeaderElection will be available.

ZooKeeper のサーバ間はどのようなやりとりがされているのか?

  • ZooKeeper は1台 Leader と呼ばれるサーバーがおり、残りが Follower として動作している。

ServerA(Follower)
ServerB(Follower)
ServerC(Leader)

  • 基本的に通信は Leader と Follower の間でのみ行われ、Follower 間での通信は発生しない。

ServerA(Follower)「Leader とだけやり取りします」
ServerB(Follower)「Leader とだけやり取りします」
ServerC(Leader)「全 Follower とやり取りするよ」

  • Follower 間の通信は Leader を探すときと Leader を選出する時に発生する。

ServerA(Follower)「Leader は誰ですか?」
ServerB(Follower)「俺じゃないよ」
ServerC(Leader)「僕が Leader だよ」

ZooKeeper のクライアントはどのサーバーに接続するのか?

  • 接続先はランダムに決定する(はず)。
  • 特にどのサーバーが現在の Leader なのかは、クライアント側としては関係ない。

クライアント「どのサーバにお願いしようかな。A~Cの誰でもいいや。」

ZooKeeper のサーバー間はどのようにしてデータを同期しているのか?

  1. クライアント側から何らかのデータ更新要求を受けた ZooKeeper サーバーはそれをまず Leader へ報告する。 (Leader が直接要求を受けた場合はそのまま処理を継続)
  2. Leader は報告を受けた順に(ひとつずつ)処理するが、まず 全 Follower に対してデータ更新の提案(proposal)を行う。
  3. Leader は過半数以上の Follower (5台構成なら3台以上)から同意(agreement)を得られれば、そのデータ更新作業を commit する。
  4. そのため、ある別々のクライアントからのデータ参照要求が同時にあったとしても、サーバーによって異なる結果を返すことはない。

ServerA(Follower)「Leader!クライアントからデータの更新依頼がありました!」
ServerC(Leader)「ちょっと待ってくれ、一つずつしか処理できんから」
ServerC(Leader)「みんな!このデータ更新するよー」
ServerA(Follower)「了解です!」
ServerB(Follower)「承知しました!」
ServerC(Leader)「よーしコミットするよ!」
クライアント「どのサーバーに聞いても同じ回答くれるから助かるよ」