普通の人でもわかる Paxos

Preview:

Citation preview

普通の人でもわかるPaxos

@tyonekura

前提

•  一番シンプルなPaxosプロトコル(PaxosMadeSimple)を紹介します。

Paxosとは

•  ある値を、過半数のノードに書き込むプロトコル。もうちょっと正確には、過半数のノードに書き込まれた時点で合意したとみなせるプロトコル。

•  途中でネットワークが途切れたり、ノードが死んだり、生き返ったり、色々しても大丈夫。

登場人物•  クライアント– プロポーザに、書き込みをお願いする人– 登場人物といっておきながら、話はプロポーザが値を持ってから始めればいいので、以下登場しません。

•  プロポーザ– アクセプタの過半数に同じ値を書き込むよう頑張る

•  アクセプタ– プロポーザから来た値をよきにはからう(後述)

•  リスナ– 最後に、過半数のアクセプタから値をゲット。

基本的な動き(フェーズ1)

•  フェーズ1a(プロポーザ側)– アクセプタにお伺いをたてる。その際、メッセージIDを添える。

•  フェーズ1b(アクセプタ側)– 初めてのお伺いや、これまで約束したお伺いより高いIDだったら、約束を返す。もし今までアクセプトをしていたら、その値も返す。

– これまで約束したお伺いより低いIDは無視する。

オレンジのキーワードは、送られるメッセージの種類を指しています。

基本的な動き(フェーズ2)

•  フェーズ2a(プロポーザ側)– 過半数のアクセプタから約束が返ってこなかったら、どこかで諦めて、メッセージIDを増やして最初からやりなおし。

– 過半数のアクセプタから約束が返ってきたら、メッセージIDと値を添えてアクセプタにプロポーズを送る。

– プロポーズを送る際に、もしも約束に(ID,値)の組がついて返ってきたら、自分の値を、返ってきた約束の中で一番高いIDの値で書き換えてプロポーズを送る。(IDは自分の。なぜなら、約束が返ってきたということは、その時点で自分のIDが一番高い。)

基本的な動き(フェーズ2)

•  フェーズ2b(アクセプタ側)– プロポーズのIDが最後に約束したIDか、それより大きい場合、アクセプトする。

– プロポーズのIDが最後に約束したIDより小さい場合、お断りする。

基本的な動き(終わり)

•  フェーズ2c?(プロポーザ側)– 過半数からアクセプトが返ってきたら終了– 過半数に達せずタイムアウトするか、過半数からお断りされたらメッセージIDを増やして最初に戻る。

•  リスナーは、アクセプタに聞いて回って、過半数のアクセプタが同じ値を持っていたらその値を信じる。

と、こう書くと

•  よくわからなくなる。•  たぶん、例が少ないのでわからないのだと思う。

•  なので、以下パラパラ漫画

一番単純なケース

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

お伺い

お伺い

お伺い

0

0

0

プロポーザ

一番単純なケース

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(1)

いいですよ(1)

いいですよ(1)

約束

約束

約束

1

1

1

プロポーザ

一番単純なケース

アクセプタ1

アクセプタ2

アクセプタ3

鈴木です。(1)

鈴木です(1)

鈴木です(1)

プロポーズ

プロポーズ

プロポーズ

1

1

1

プロポーザ

一番単純なケース

アクセプタ1

アクセプタ2

アクセプタ3

プロポーザ

アクセプト(1)

アクセプト(1)

アクセプト(1)

1

1

1

鈴木

鈴木

鈴木

一番単純なケース

アクセプタ1

アクセプタ2

アクセプタ3

リスナー

1

1

1

鈴木

鈴木

鈴木

鈴木ね

アクセプタ一台故障

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

お伺い

お伺い

お伺い

0

0

0

プロポーザ

アクセプタ一台故障

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(1)

いいですよ(1)

約束

約束

1

0

1

プロポーザ

アクセプタ一台故障

アクセプタ1

アクセプタ2

アクセプタ3

鈴木です。(1)

鈴木です(1)

プロポーズ

プロポーズ

1

0

1

プロポーザ

アクセプタ一台故障

アクセプタ1

アクセプタ2

アクセプタ3

プロポーザ

アクセプト(1)

アクセプト(1)

1

0

1

鈴木

鈴木

アクセプタ一台故障

アクセプタ1

アクセプタ2

アクセプタ3

リスナー

1

0

1

鈴木

鈴木

鈴木ね

アクセプタ一台故障と思ったら生き返った

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

お伺い

お伺い

お伺い

0

0

0

プロポーザ

アクセプタ一台故障と思ったら生き返った

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(1)

いいですよ(1)

約束

約束

1

1

1

プロポーザ

アクセプタ一台故障と思ったら生き返った

アクセプタ1

アクセプタ2

アクセプタ3

鈴木です。(1)

鈴木です(1)

プロポーズ

プロポーズ

1

1

1

プロポーザ

プロポーズ

鈴木です(1)

約束返ってきてなくてもとりあえずプロポーズする。

アクセプタ一台故障と思ったら生き返った

アクセプタ1

アクセプタ2

アクセプタ3

プロポーザ

アクセプト(1)

アクセプト(1)

1

1

1

鈴木

鈴木

アクセプト(1)

いままでで一番IDが大きいのでアクセプトする。鈴木

アクセプタ一台故障と思ったら生き返った

アクセプタ1

アクセプタ2

アクセプタ3

リスナー

1

1

1

鈴木

鈴木

鈴木ね

鈴木

プロポーザ2人

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

お伺い

お伺い

お伺い

0

0

0

プロポーザ

プロポーザ2人

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(1)

いいですよ(1)

約束

約束

1

1

1

プロポーザ

いいですよ(1)約束

プロポーザ2人

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(2)

プロポーズしていいですか?(2)

プロポーズしていいですか?(2)

お伺い

お伺い

お伺い

1

1

1

プロポーザ2人

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(2)

いいですよ(2)

約束

約束

2

2

2

いいですよ(2)約束

プロポーザ2人

アクセプタ1

アクセプタ2

アクセプタ3

鈴木です。(1)

鈴木です(1)

プロポーズ

プロポーズ

2

2

2

プロポーザ

プロポーズ

鈴木です(1)

プロポーザ2人

アクセプタ1

アクセプタ2

アクセプタ3

プロポーザ

リジェクト(2)

リジェクト(2)

2

2

2

リジェクト(2)

プロポーザ2人

アクセプタ1

アクセプタ2

アクセプタ3

佐藤です。(2)

佐藤です(2)

プロポーズ

プロポーズ

2

2

2

プロポーズ

佐藤です(2)

プロポーザ2人

アクセプタ1

アクセプタ2

アクセプタ3

プロポーザ

アクセプト(2)

アクセプト(2)

2

2

2

佐藤

佐藤

アクセプト(2)

佐藤

プロポーザ2人

アクセプタ1

アクセプタ2

アクセプタ3

リスナー

2

2

2

佐藤

佐藤

佐藤ね

佐藤

もしリスナーが選ぶ前にリトライしたら敗者復活?

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(3)

プロポーズしていいですか?(3)

プロポーズしていいですか?(3)

お伺い

お伺い

お伺い

2

2

2

佐藤

佐藤

佐藤

おや?約束に、他人の名前が。。

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(佐藤、2)

いいですよ(佐藤、2)

約束

約束

いいですよ(佐藤、2)約束

3

3

3

佐藤

佐藤

佐藤

なぜ他人の名前で。。せつない。。

アクセプタ1

アクセプタ2

アクセプタ3

佐藤です。(3)

佐藤です(3)

プロポーズ

プロポーズ

2

2

2

プロポーズ

佐藤です(3)

2

2

2

佐藤

佐藤

佐藤この後の処理は結果が変わらないので、実装依存

プロポーザ3人

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

お伺い

お伺い

お伺い

0

0

0

プロポーザ

プロポーザ3人

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(1)

いいですよ(1)

約束

約束

1

1

1

プロポーザ

いいですよ(1)約束

プロポーザ3人

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(2)

プロポーズしていいですか?(2)

お伺い

お伺い

1

1

1

二人目の時、1台不調

プロポーザ3人

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(2)

約束

1

2

2

いいですよ(2)約束

プロポーザ3人(1台目復活)

アクセプタ1

アクセプタ2

アクセプタ3

鈴木です。(1)

鈴木です(1)

プロポーズ

プロポーズ

1

2

2

プロポーザ

プロポーズ

鈴木です(1)

プロポーザ3人

アクセプタ1

アクセプタ2

アクセプタ3

プロポーザ

アクセプト(1)

リジェクト(2)

1鈴木

2

2

リジェクト(2)

2人目がアクセプタ2にプロポーズしたところで。。

アクセプタ1

アクセプタ2

アクセプタ3

佐藤です(2)プロポーズ

1鈴木

2

2佐藤

まだとどいてない。

まだとどいてない。

アクセプト(2)

3人目が登場。

アクセプタ1

アクセプタ2

アクセプタ3

1鈴木

2

2佐藤

プロポーズしていいですか?(3)

プロポーズしていいですか?(3)

お伺い

お伺い

プロポーズしていいですか?(3)

お伺い

3人目が登場。

アクセプタ1

アクセプタ2

アクセプタ3

3鈴木

3

3佐藤

いいですよ(1,鈴木)約束

いいですよ(3)約束

いいですよ(2,佐藤)約束

3人目は佐藤を推す。

アクセプタ1

アクセプタ2

アクセプタ3

3鈴木

3

3佐藤

佐藤です。(3)プロポーズ

プロポーズ

プロポーズ

佐藤です(3)

佐藤です(3)

もしこの前に佐藤さんのプロポーズが届いたら、それはID2なので無視される。

プロポーザ3人

アクセプタ1

アクセプタ2

アクセプタ3

プロポーザ

アクセプト(3)

アクセプト(3)

3

3

3

佐藤

佐藤

アクセプト(3)

佐藤

プロポーザ3人

アクセプタ1

アクセプタ2

アクセプタ3

リスナー

3

3

3

佐藤

佐藤

佐藤ね

佐藤

その他

•  色んなパターンを試しても、過半数のアクセプタといずれかのプロポーザが生きているなら、いずれは合意が取れるようになっています。

•  よくできてますね。。

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

プロポーズしていいですか?(1)

お伺い

お伺い

お伺い

0

0

0

プロポーザ

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(1)

いいですよ(1)

約束

約束

1

1

1

プロポーザ

いいですよ(1)約束

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(2)

プロポーズしていいですか?(2)

プロポーズしていいですか?(2)

お伺い

お伺い

お伺い

1

1

1

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(2)

いいですよ(2)

約束

約束

2

2

2

いいですよ(2)約束

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

鈴木です。(1)

鈴木です(1)

プロポーズ

プロポーズ

2

2

2

プロポーザ

プロポーズ

鈴木です(1)

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

プロポーザ

リジェクト(2)

リジェクト(2)

2

2

2

リジェクト(2)

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

プロポーズしていいですか?(3)

プロポーズしていいですか?(3)

プロポーズしていいですか?(3)

お伺い

お伺い

お伺い

2

2

2

プロポーザ

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

いいですよ(3)

いいですよ(3)

約束

約束

3

3

3

プロポーザ

いいですよ(3)約束

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

佐藤です。(2)

佐藤です(2)

プロポーズ

プロポーズ

3

3

3

プロポーズ

佐藤です(2)

ライブロック

アクセプタ1

アクセプタ2

アクセプタ3

プロポーザ

リジェクト(3)

リジェクト(3)

3

3

3

リジェクト(3)

以下、永遠につづくかも。(ランダムでsleep入れるとか、工夫する。)

以下、混乱しやすい点を

これらはPaxosの範疇じゃない

•  トランザクション– Paxosは、過半数にある値を届けて合意を取るものであって、広い意味での(DB的な)トランザクションではない。

•  クラスタメンバーシップ– とりあえず、メンバーは固定。アクセプタが増えたり減ったりする場合は実装側で。(メンバーシップ情報をPaxosで同期したりとか。)

これらはPaxosの範疇じゃない

•  プロポーザ選択– 適当にどれか1台をプロポーザにする。– クライアントが複数のプロポーザを選んで同時に別々の提案をしても、大丈夫。

•  過半数に達した後の少数側の扱い– 実装上はデータ同期させたほうがいいと思うけど、それはPaxosの範疇外

これらはPaxosの範疇じゃない•  ビザンチン障害

–  具体的には、–  メッセージID偽装

•  約束されてないIDでプロポーズを投げる•  一意じゃないIDというのも、これに含まれると思う。

–  アクセプタがアクセプトしてない値を捏造–  アクセプタが約束してないIDを返す–  等等

•  過半数を超える障害–  例:9台5台のアクセプタがアクセプトした、と思ったら、その5台のうち1台が壊れた。

–  実用上は過半数、というところを変えてあげればOK.–  例:9台中5台に書き込めたらOKではなく、9台中7台に書き込めたらOKにして、アクセプトまでは2台障害に耐え、リスナーがチェックするときは5台でOKにするとか。

これらはPaxosの範疇じゃない

•  メッセージIDをどうやって一意にするか•  Macアドレス+シーケンス番号とか。•  ノードID+シーケンス番号とか。– シーケンス番号同士を比べて、同じだったらノードIDを比べる。

– ノード番号同士を比べて、同じだったらシーケンス番号を比べる。

– 普通は前者。後者は、複数プロポーザケースに必ず1台が勝つことになるが、別にそれでもPaxos的には問題ない。

Recommended