SlideShare a Scribd company logo
1 of 32
Download to read offline
2022/01/28 sho nakazono, CD研 C革P 革シG
#14 分散合意 その2
詳説データベース輪読会
14.4 Raft
• (Paxosにくらべて) 理解しやすく実装しやすい合意アルゴリズム.

• NSDIのReviewerは “Paxosを理解できるのは世界で5人もいないだろう” と述べていた.

• Raftのauthorsはpaxosをある程度理解して,paxosのforkを作るまで1年かかった

• USENIX ATC’14 にて “In Search of an Understandable Consensus Algorithm” という論文で発表された.

• そこに至るまでに3年間rejectされ続けたらしい.

• NSDI 2013, SOSP 2013, NSDI 2014…

• “理解しやすく実装しやすい” がContributionとして弱かったとか.

• 論文のほうも,5章に入るまでずっとイントロのような感じの記述が続いていて,苦労が伺える

• リファレンス実装は “LogCabin” として公開された.ソフトウェアとしては etcd, CockroachDB, Consul などが使っている.

• https://github.com/logcabin/logcabin
Raft is more understandable than paxos
14.4 Raft: Properties
1. Safety:
• ビザンチン障害を除く,パケットロス,ネットワーク断,遅延,duplication, reordering に対応できる.

2. Available:
• (N/2)+1台までの障害に対応する可用性がある.
3. Timing:
• 実時間的なタイミングがプロトコルに含まれない.
• これを含んでいると,最悪の場合,可用性に問題がある.
4. Performance:
• 過半数のノードから応答が得られた時点で,リクエストが完了する => 遅いノードに性能が律速されない
14.4 Raft: Properties
14.4 Raft
• プロトコルは Atomic Broadcast/Multi-Paxosと類似点がある

• 単一のリーダーを選出し,アトミックな決定を行い,メッセージの順序を確定する点が類似して
いる

• 参加ノードの役割は3つ(次ページ).

• 全てのノードに共通する要素として, Replicated State Machine を使う.

• 各ノードで,ステートマシンが実行する一連のコマンドのログを格納する

• 同じ順序で同じログを適用すれば,ステートマシンが同じ出力を返す

• Failure modelは Fail-stop + delayed/lost messages
14.4 Raft: Replicated State Machine
1. クライアントはサーバに要求を送信する.

2. コンセンサスアルゴリズムがログを管理する.

3. ログを順序通りに実行すると,同じステートマ
シンが得られる.

※ ステートマシンがdeterministicである前提がある.

障害が発生した場合にも,同じログがすべてのノード
で得られるのであれば,単一のサーバとして透過的に
扱える,というのが Replicated State Machine.
14.4 Raft: Novel Features
• Raftの(他の合意アルゴリズムと比較した際の)特徴は以下

1. Strong leader
• リーダの役割が強い.例えば,ログはリーダから他のノードにのみ流れる.

• ログの流れがシンプルで,理解しやすい.

2. Leader election
• リーダ選出の仕組みにrandomized timerを使用している.

• 他の合意アルゴリズムにも必ず登場する heartbeat の仕組みにほんの少しの修正を加えるだけでよ

3. Membership changes
• ノードの追加/削除などメンバシップの変更に joint consensus アプローチを用いている.

• 変更前/変更後で大部分のcon
fi
gurationを共有するというもので,変更を行いながらクライアントの要求を受け付けられる.
14.4 Raft: Nodes
• 参加ノードの役割は以下の3つ

1. Follower
• ログエントリを永続化する受動的な参加ノード.Paxosにおけるアクセ
プタ/ラーナーと類似.

2. Candidate
• Follower が立候補するとなる役割.過半数の投票を得るとLeader にな
る.立候補のトリガはタイムアウト.

3. Leader
• クライアントの要求を処理する.任期(term)がある.基本的に再任
される.

• 各サーバの通信の際には必ず自身が観測する最大のtermを送る.

• 自分が最新ではないtermに属していると気づいたleader/candidateは
followerに戻る.
14.4 Raft: RPC
• Raftは2つのRPCからなる.(# 実質3つでは?)

1. AppendEntries RPC
ログの送付を行う.leaderからfollowerに流れる.
ログが空の場合,leaderからのハートビートとして機能する.
i.e., ハートビートが送られてくる,ということは,「俺がleaderだぞ」という意味.
2. RequestVote RPC
Leader election の開始を告げる.candidateから送られてくる.

これを受け取った場合, termが最新ならば,誰かひとりに投票: `VoteGranted` をtrueにしてレスポンスする.
14.4 Raft: Leader Election
• リーダは任期中,heartbeatを他のノードに送り続ける.

• Heartbeatがタイムアウトした際,フォロワーはtermをincrementして,自身がCandidateとなり,新たな任期を開始する.

• RequestVote RPC を発行し,全ノードに投票を募る.

• RequestVote RPCを受け取った場合,RPCについている任期が自分と同じ & 自分と同じログを全て持っている
CandidateからのRPCであれば, voteGranted = true にしてレスポンスする.そうでない場合は,棄却する.

• 誰かが選挙で勝つか,新たな投票が始まるまで続行.

• 過半数の投票を得たノードは,他のノードにハートビートを送り,投票の終了を知らせる.

• 同時に複数のCandidateが起こりうるし,複数のtermが存在しうる.無限に投票を繰り返す可能性がある.

• これを解決するのが,randomized timeout.
14.4 Raft: Randomized Timeout
• RaftはCandidateが同時に起こって投票が無限に継続するのを防ぐため,150-300ms の選挙タイ
ムアウトを各サーバにランダムに割り振る.

• タイムアウト中は,candidateになれない.

• 投票が割れても,最速でタイムアウトを抜けるサーバが次のCandidateになり,他のサーバが
タイムアウト中に RequestVote RPCを発行できるので,優先権がついた形になり,無限に投
票を繰り返す可能性が下がる.

• もともとはrankingにしようとしていたが,availabilityの問題からretry形式にした.
Raft uses randomized election timeouts to ensure that split votes are rare and that they are resolved quickly. To
prevent split votes in the
fi
rst place, election timeouts are chosen randomly from a
fi
xed interval (e.g., 150–300ms).
• タイムアウトの時間設定によって,リーダ不在の時間が変化す
る,という実験.

• 上図: small amount randomization

• 下図: high amount randomization

タイムアウトの時間が同じ(150ms-150ms) の場合,80%程度のケー
スで100000ms (1分半以上) リーダ選出にかかることになる.

リーダ不在の時間だけを見ると12-24ms が一番良さそうだ
が・・・?

> However, lowering the timeouts beyond this point violates Raft’s
timing requirement: leaders have di
ffi
culty broadcasting heartbeats
before other servers start new elections. This can cause
unnecessary leader changes and lower overall system availability.
We recommend using a conservative election timeout such as 150–
300ms; such timeouts are unlikely to cause unnecessary leader
changes and will still provide good availability.
リーダが細かく切り替わっていくだけで,リクエストを処理できて
はいない,ということ?
Raft: AppendEntries RPC
• Leaderが決定している間は,クライアントからの要求を処理できる.

1. どのノードも,クライアントからの要求をLeaderに転送する

2. Leaderのローカルログにエントリを追記する

3. Leaderから全フォロワーにAppendEntries RPCを送信

4. 過半数のレスポンスが得られたらCommitted マークをLeaderのログに付ける

5. クライアントにCommittedを応答する.

• この後でも,全てのフォロワーからレスポンスが得られるまで,無制限に再送信する.

6. Committed マークが付いたことをFollowerに知らせる (AppendEntries RPCを再送).
14.4 Raft: Log Matching Property
• 前者: ログエントリのインデックスと任期が同じならば,必ず同じ操作

• 後者: そのようなentriesがあるならば,それ以前のログも全て同じ.

Raft はこの Log Matching Propertyを提供している.これによって,一貫性を維持するための処理が簡単かつ理解しやすくなる.

# 例えば,一定期間sleep/faultしていたとしても,”index 3のitemはterm 4 のもの” という AppendEntries RPCを受け取っただけで,自分の持っ
ているエントリに不足がないか判断できる

A. index 3, term 4 のログを持っている => 一定時間死んでいたけど,ログはすべて正しいものを持っている

B. Index 1 までしか持ってない! => 無限再送される AppendEntries RPCを待てば,いつか う.

C. Index 3は term 4ではない => サーバ構成が変更されたことが検出できる.
• If two entries in different logs have the same index and term, then they store the same command.


• If two entries in different logs have the same index and term, then the logs are identical in all preceding entries.
• Raftでは,followerのcrashはログに影響を与えないが,
Leaderのcrashによっていくつかのシナリオがありうる.

(a-b): ログが足りない.

(c-d): リーダにとって未コミットのエントリを持っている.

(e-f): ログが足りない & 未コミットもある.

すべての場合に対処できるよう,リーダーは,常に以下を行
う

• 全てのfollowerからnextIndex[]を収集する.[10, 5, 11, 13…]

• 自分のnextIndexを最新とする.

• AppendEntries RPCを使ってLeaderとの間でLog と Term
が一致するエントリまでnextIndexをデクリメントさせてい
く.

• nextIndex がLeaderと一致するまでAppendEntriesを行う.
14.4 Raft: Committing Entries From Previous Terms
• AppendEntries RPCで過半数にログを複製したが,committedと通知する前に
Leaderがcrashした場合,新しいLeaderはこれをcommittedだと判断できる.

• 過半数にログを複製してあると,そのログを持っているノードしか次の選挙に勝て
ない.そして,選挙に勝ったleaderのローカルログはcommittedだとみなされる.
a. S1 が 2台に term 2を複製,そしてcrash

b. S5 が term 3 のleaderに,そしてcrash

c. S1 が復帰して新たなterm 2 を過半数に送付できた場
合,過半数が取れているので,term 3 を持っている
ノード (S5) は選挙に勝てない.必ず (e) になる

d. 逆に, term 3 が先に過半数に送付できた場合,選挙に
勝つので, term 2 は棄却される
14.4 Raft: Cluster Membership Changes
• サーバ構成をオンラインで変更すると,選挙やログ複製の処理も一貫性を失う.

• サーバ構成をアトミックに切り替えることは不可能なため.

• 例えば,2つのリーダが同じtermに同居する,ということもありえてしまう.

• Raftはオンラインでサーバ構成を変更できるよう, joint consensus アプローチを作った.
14.4 Raft: Joint Consensus
• Raftでは,構成を変更するという処理を,ログエントリとして扱う.

• は旧構成. は新構成.

• は,旧構成の過半数と新構成の過半数,両方を使う

• 構成変更のために,まず をコミットする.

• その次に をコミットする.

• に自分が存在しないノードは, のAppendEntries RPC
を見たら,即シャットダウンできる

• エントリがcommitされているか否かに依らず,持っている最新のエン
トリを使う.

• がcommitされていなくとも, を使う.

• を使っているleaderがいる => 既に はコミット済み

• => 単独でコミットできるログは存在しない => 安全
Cold Cnew
Cold,new
Cold,new
Cnew
Cnew Cnew
Cnew Cnew
Cnew Cold,new
Cold
14.4 Raft: Joint Consensus
• いくつかの問題/最適化/細かいアプローチがある.

• 新規に追加されたノードは,これまでのログを全て反映しきるまで投票に参加できないので,足を引っ張る
ことになる.そのため,”non-voting members” になってログだけを受け取ることができる.

• に自分が含まれていないリーダは, がコミットされるまでは動き続ける.

• に自分が含まれていないノードは, AppendEntries RPC (heartbeat) を受け取れないため,タイムアウ
トが発生したとみなして他のサーバに RequestVote を行ってしまう.

• これに対処するため,各ノードは,現在のリーダから指定されたタイムアウト時間がすぎるまでは,
RequestVote RPCを棄却する.

• # この「タイムアウト時間の指定」がどこで行われるのかわからない. AppendEntries RPC?
Cnew Cnew
Cnew
14.4 Raft: Misc
• ログが単調増加するため,スナップショットを使う.

• リーダの持つログは常に最新なので,リーダに作成させるのが簡単.

• Raft のゴールは Linearizable & Exactly-Once. しかしcrashした場合など,何回か同じクライアントの命令がステート
マシンに対して実行されうる.

• クライアントの命令にserial numberを割り振って,ステートマシンに記録しておけばOK.

• Read-only の命令はログを追加しないのでフォロワーが即実行できる? -> できない

• リーダ以外,最新のデータを持っている保証はない

• そして,リーダですらも知らないうちに新しい任期のリーダが誕生している可能性がある

• これに対処するために,Read-only 命令であっても書込みと同様に扱う. no-op 命令を含むログとしてコミット.
Raft Visualizationを見てみよう
• https://raft.github.io/
14.5 ビザンチン合意
• これまでの合意アルゴリズムはすべて非ビザンチン障害が前提.

• 非ビザンチン障害を前提にすると,参加ノードの数やコミットまでのRTTを減らせる.

• ビザンチン障害を前提にすると,色々と難しい.

• 悪意ある振る舞い,バグ,設定ミス,ハードウェア異常,データの破損など

• あるメッセージが正しいかどうかについて検証するため,クォラム内の各ノードが相互
通信する必要があり, のメッセージが必要になる.

• この章では, Practical Byzantine Fault Tolerance (PBFT) について議論する.
N2
14.5 PBFT
• PBFTの前提:

• Independent node failures: 障害は個別に発生する.システム全体が乗っ取られること
はない

• Weak synchrony: 障害が発生することはあるが,無限にではなく,いつかは復旧される

• Encrypted messages: ノード間の通信はすべて暗号化される.これによってメッセージ
の偽造を防げる…が,障害のあるノードは結局秘密 を漏洩してしまう可能性があるの
で,暗号化されているからといってメッセージが無制限に信頼できるわけではない.
14.5.1 PBFTアルゴリズム
• PBFTがsafetyとlivenessを満たすために許容する障害レプリカの数は, 

• nは参加ノード数.したがって,f の障害ノード数を許容するには 必要.

• クラスタ構成の中で,PBFTは views という概念を使う.各viewにおいて,以下が存在する

• View: ID v をもつ.primaryで障害が発生すると変更される.

• Primary: v % n のノードがこう呼ばれる.クライアントの要求を処理する.

• Backup: primaryからブロードキャストされる要求を実行し,クライアントにレスポンス.

• f+1 のレプリカから同じ結果が応答されたら,クライアントはコミットとみなせる.
(n − 1)/3
n = 3f + 1
14.5.1 PBFTアルゴリズム
• 以下がPBFTのプロトコルの流れ.

• Primaryがクライアントのリクエストを受け取る.

• Pre-Prepare phase:
• primaryから{v, n, payload, digest(payload)} をブロードキャスト.nは単調増加するシーケンス番号. digestはデジタル署名を行う.

• backupは,自身のviewが v と一致している digestの計算が一致する際,メッセージを受け入れる.

• Prepare phase:
• Backupは,Prepare メッセージ {v, n, digest(payload), i} をブロードキャスト. i はレプリカのユニーク番号.

• 同じ Prepare メッセージを 2f 回,異なるbackupから受け取った場合にのみ Prepare phaseを抜ける.

• Commit phase:
• Backupは,このメッセージについてのCommit メッセージを 2f + 1 のノードから収集したらコミットをクライアントに返す.

• クライアントは f+1 のノードからCommitを返却してもらったら,コミットと判断できる
14.5.1 PBFTアルゴリズム: 正常系
Figure 1: Normal Case Operation
• PBFTでは,フェーズの間に必ず,各ノードが 2f + 1 のメッセージをそれぞれ収集する.そしてdigestをチェックするた
め,不正なメッセージは防止できる.

• 上図は primary = 0, f=1. P3 で障害が発生したため,応答を返さなくなっている.しかし,prepare -> commit で 各ノー
ドが 2f のprepare を収集しており,commitも 2f +1を収集しているため,正常に続行できる.

• Primaryに障害が発生した際は “view changes” というプロトコルが走り,primaryが交代する.
14.5.2 リカバリとチェックポイント
• 各レプリカは,メッセージを永続化する.

• f+1 のノードで命令が実行されるまで保持しておく必要がある.

• メッセージを転送すれば,NW分断の後でもリカバリが可能・・・だが,そのメッセージが正しいものであることを保証し
なければならない.

• 各メッセージを反映して処理を進めながら,digestを再検証していけばよい.が,コストが高すぎる.

• そこで,定期的に stable checkpoint をとる.

• 最新のシーケンス番号 n と,現在の状態に対するdigest をブロードキャストする.

• 2f+1 のレプリカが正しいと応答してきた場合,チェックポイントが取れている証左になる. n 以下のidのメッセージをすべ
て破棄できる.

• # チェックポイントは全レプリカで共通の断片ではなく,各ノードが各自に勝手に行う.
14.5.1 PBFTアルゴリズム: 異常系
• Primaryが動作していない,など,backupが異常の疑いを検出した際,view
changes というプロトコルが走る.

• それ以降のメッセージへの応答を停止し,自分がprimaryになろうとする.

• viewの変更 { v+1, n, C, P, i} をbroadcastする.n は 自身が持つ最後の
チェックポイントのメッセージ番号.Cはそのチェックポイントに応答し
た2f+1 のノードのメッセージ集合.Pはまだチェックポイントに含まれて
いないリクエストの集合.

•
14.5.2 PBFT summary
• PBFTは,敵意が含まれる可能性のあるネットワークで利用するもの.

• ビザンチン障害耐性を持つプロトコルは,メッセージ数が増大するという欠点がある.PBFTも,
(primaryを立てているのにも関わらず) ブロードキャストを多用してしまっている.

• 参加ノードの台数 N や 故障許容ノードの数 f というパラメータを全レプリカで共有しなければなら
ない.これは前述したweak synchrony があるから許されている.パブリックブロックチェーン等の
世界ではその点で評価されていない(と思う).
• > 大半の場合は,ノード間の通信を認証して暗号化すれば十分ですが,システムのパーツ間
に信頼性がない場合には,PBFTに類似したアルゴリズムを導入しなければなりません.
14.6 まとめ
• Multi-paxos: proposerが継続する.複数の値についてreplicationできる.
• Fast paxos: fast ラウンドが存在し,メッセージの数が削減されている.
• EPaxos:メッセージ間の依存関係を解決し,イベントの順序が確立できる.
• Flexible Paxos: クォラムの要件を緩和する.
• Raft: 強いリーダシップがあり,Paxosの各要素がdecompositionされ,理解しやすい.
• PBFT: 敵意が含まれる(HW故障なども含む) 環境で安全に合意できる.
References
[1] Diego Ongaro, John K. Ousterhout: In Search of an Understandable
Consensus Algorithm. USENIX Annual Technical Conference 2014: 305-319

[2] https://raft.github.io/slides/linkedin2014.pptx

[3] Miguel Castro, Barbara Liskov (1999) Practical Byzantine Fault Tolerance

More Related Content

What's hot

そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?
takezoe
 

What's hot (20)

ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方ストリーム処理を支えるキューイングシステムの選び方
ストリーム処理を支えるキューイングシステムの選び方
 
トランザクションの設計と進化
トランザクションの設計と進化トランザクションの設計と進化
トランザクションの設計と進化
 
TLS, HTTP/2演習
TLS, HTTP/2演習TLS, HTTP/2演習
TLS, HTTP/2演習
 
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
Apache Kafkaって本当に大丈夫?~故障検証のオーバービューと興味深い挙動の紹介~
 
Cassandraとh baseの比較して入門するno sql
Cassandraとh baseの比較して入門するno sqlCassandraとh baseの比較して入門するno sql
Cassandraとh baseの比較して入門するno sql
 
PGOを用いたPostgreSQL on Kubernetes入門(PostgreSQL Conference Japan 2022 発表資料)
PGOを用いたPostgreSQL on Kubernetes入門(PostgreSQL Conference Japan 2022 発表資料)PGOを用いたPostgreSQL on Kubernetes入門(PostgreSQL Conference Japan 2022 発表資料)
PGOを用いたPostgreSQL on Kubernetes入門(PostgreSQL Conference Japan 2022 発表資料)
 
TiDBのトランザクション
TiDBのトランザクションTiDBのトランザクション
TiDBのトランザクション
 
初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!初心者向けMongoDBのキホン!
初心者向けMongoDBのキホン!
 
Cassandraのしくみ データの読み書き編
Cassandraのしくみ データの読み書き編Cassandraのしくみ データの読み書き編
Cassandraのしくみ データの読み書き編
 
VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)
VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)
VSCodeで作るPostgreSQL開発環境(第25回 PostgreSQLアンカンファレンス@オンライン 発表資料)
 
そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?
 
Docker Tokyo
Docker TokyoDocker Tokyo
Docker Tokyo
 
Marp Tutorial
Marp TutorialMarp Tutorial
Marp Tutorial
 
トランザクションの並行実行制御 rev.2
トランザクションの並行実行制御 rev.2トランザクションの並行実行制御 rev.2
トランザクションの並行実行制御 rev.2
 
Kafka vs Pulsar @KafkaMeetup_20180316
Kafka vs Pulsar @KafkaMeetup_20180316Kafka vs Pulsar @KafkaMeetup_20180316
Kafka vs Pulsar @KafkaMeetup_20180316
 
コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線コンテナネットワーキング(CNI)最前線
コンテナネットワーキング(CNI)最前線
 
WiredTigerを詳しく説明
WiredTigerを詳しく説明WiredTigerを詳しく説明
WiredTigerを詳しく説明
 
Fluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターンFluentdのお勧めシステム構成パターン
Fluentdのお勧めシステム構成パターン
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
iostat await svctm の 見かた、考え方
iostat await svctm の 見かた、考え方iostat await svctm の 見かた、考え方
iostat await svctm の 見かた、考え方
 

More from Sho Nakazono

More from Sho Nakazono (11)

述語ロックの歴史 r2
述語ロックの歴史 r2述語ロックの歴史 r2
述語ロックの歴史 r2
 
Checkpointing Algorithms on In-memory DBMS
Checkpointing Algorithms on In-memory DBMSCheckpointing Algorithms on In-memory DBMS
Checkpointing Algorithms on In-memory DBMS
 
LineairDBの紹介 MySQL編
LineairDBの紹介 MySQL編LineairDBの紹介 MySQL編
LineairDBの紹介 MySQL編
 
LineairDBの紹介
LineairDBの紹介LineairDBの紹介
LineairDBの紹介
 
ファントム異常を排除する高速なトランザクション処理向けインデックス
ファントム異常を排除する高速なトランザクション処理向けインデックスファントム異常を排除する高速なトランザクション処理向けインデックス
ファントム異常を排除する高速なトランザクション処理向けインデックス
 
LineairDB: Fast and Embedded Transactional Key-Value Storage
LineairDB: Fast and Embedded Transactional Key-Value StorageLineairDB: Fast and Embedded Transactional Key-Value Storage
LineairDB: Fast and Embedded Transactional Key-Value Storage
 
論文紹介: Cuckoo filter: practically better than bloom
論文紹介: Cuckoo filter: practically better than bloom論文紹介: Cuckoo filter: practically better than bloom
論文紹介: Cuckoo filter: practically better than bloom
 
輪読資料: Staring into the abyss an evaluation of concurrency control with one t...
輪読資料: Staring into the abyss  an evaluation of concurrency control with one t...輪読資料: Staring into the abyss  an evaluation of concurrency control with one t...
輪読資料: Staring into the abyss an evaluation of concurrency control with one t...
 
[xSIG 2018]InvisibleWriteRule: Extended write protocol for 1VCC
[xSIG 2018]InvisibleWriteRule: Extended write protocol for 1VCC[xSIG 2018]InvisibleWriteRule: Extended write protocol for 1VCC
[xSIG 2018]InvisibleWriteRule: Extended write protocol for 1VCC
 
論文紹介: An empirical evaluation of in-memory multi-version concurrency control
論文紹介: An empirical evaluation of in-memory multi-version concurrency control論文紹介: An empirical evaluation of in-memory multi-version concurrency control
論文紹介: An empirical evaluation of in-memory multi-version concurrency control
 
並行実行制御の最適化手法
並行実行制御の最適化手法並行実行制御の最適化手法
並行実行制御の最適化手法
 

詳説データベース輪読会: 分散合意その2

  • 1. 2022/01/28 sho nakazono, CD研 C革P 革シG #14 分散合意 その2 詳説データベース輪読会
  • 2. 14.4 Raft • (Paxosにくらべて) 理解しやすく実装しやすい合意アルゴリズム. • NSDIのReviewerは “Paxosを理解できるのは世界で5人もいないだろう” と述べていた. • Raftのauthorsはpaxosをある程度理解して,paxosのforkを作るまで1年かかった • USENIX ATC’14 にて “In Search of an Understandable Consensus Algorithm” という論文で発表された. • そこに至るまでに3年間rejectされ続けたらしい. • NSDI 2013, SOSP 2013, NSDI 2014… • “理解しやすく実装しやすい” がContributionとして弱かったとか. • 論文のほうも,5章に入るまでずっとイントロのような感じの記述が続いていて,苦労が伺える • リファレンス実装は “LogCabin” として公開された.ソフトウェアとしては etcd, CockroachDB, Consul などが使っている. • https://github.com/logcabin/logcabin
  • 3. Raft is more understandable than paxos
  • 4. 14.4 Raft: Properties 1. Safety: • ビザンチン障害を除く,パケットロス,ネットワーク断,遅延,duplication, reordering に対応できる. 2. Available: • (N/2)+1台までの障害に対応する可用性がある. 3. Timing: • 実時間的なタイミングがプロトコルに含まれない. • これを含んでいると,最悪の場合,可用性に問題がある. 4. Performance: • 過半数のノードから応答が得られた時点で,リクエストが完了する => 遅いノードに性能が律速されない
  • 6. 14.4 Raft • プロトコルは Atomic Broadcast/Multi-Paxosと類似点がある • 単一のリーダーを選出し,アトミックな決定を行い,メッセージの順序を確定する点が類似して いる • 参加ノードの役割は3つ(次ページ). • 全てのノードに共通する要素として, Replicated State Machine を使う. • 各ノードで,ステートマシンが実行する一連のコマンドのログを格納する • 同じ順序で同じログを適用すれば,ステートマシンが同じ出力を返す • Failure modelは Fail-stop + delayed/lost messages
  • 7. 14.4 Raft: Replicated State Machine 1. クライアントはサーバに要求を送信する. 2. コンセンサスアルゴリズムがログを管理する. 3. ログを順序通りに実行すると,同じステートマ シンが得られる. ※ ステートマシンがdeterministicである前提がある. 障害が発生した場合にも,同じログがすべてのノード で得られるのであれば,単一のサーバとして透過的に 扱える,というのが Replicated State Machine.
  • 8. 14.4 Raft: Novel Features • Raftの(他の合意アルゴリズムと比較した際の)特徴は以下 1. Strong leader • リーダの役割が強い.例えば,ログはリーダから他のノードにのみ流れる. • ログの流れがシンプルで,理解しやすい. 2. Leader election • リーダ選出の仕組みにrandomized timerを使用している. • 他の合意アルゴリズムにも必ず登場する heartbeat の仕組みにほんの少しの修正を加えるだけでよ 3. Membership changes • ノードの追加/削除などメンバシップの変更に joint consensus アプローチを用いている. • 変更前/変更後で大部分のcon fi gurationを共有するというもので,変更を行いながらクライアントの要求を受け付けられる.
  • 9. 14.4 Raft: Nodes • 参加ノードの役割は以下の3つ 1. Follower • ログエントリを永続化する受動的な参加ノード.Paxosにおけるアクセ プタ/ラーナーと類似. 2. Candidate • Follower が立候補するとなる役割.過半数の投票を得るとLeader にな る.立候補のトリガはタイムアウト. 3. Leader • クライアントの要求を処理する.任期(term)がある.基本的に再任 される. • 各サーバの通信の際には必ず自身が観測する最大のtermを送る. • 自分が最新ではないtermに属していると気づいたleader/candidateは followerに戻る.
  • 10. 14.4 Raft: RPC • Raftは2つのRPCからなる.(# 実質3つでは?) 1. AppendEntries RPC ログの送付を行う.leaderからfollowerに流れる. ログが空の場合,leaderからのハートビートとして機能する. i.e., ハートビートが送られてくる,ということは,「俺がleaderだぞ」という意味. 2. RequestVote RPC Leader election の開始を告げる.candidateから送られてくる. これを受け取った場合, termが最新ならば,誰かひとりに投票: `VoteGranted` をtrueにしてレスポンスする.
  • 11. 14.4 Raft: Leader Election • リーダは任期中,heartbeatを他のノードに送り続ける. • Heartbeatがタイムアウトした際,フォロワーはtermをincrementして,自身がCandidateとなり,新たな任期を開始する. • RequestVote RPC を発行し,全ノードに投票を募る. • RequestVote RPCを受け取った場合,RPCについている任期が自分と同じ & 自分と同じログを全て持っている CandidateからのRPCであれば, voteGranted = true にしてレスポンスする.そうでない場合は,棄却する. • 誰かが選挙で勝つか,新たな投票が始まるまで続行. • 過半数の投票を得たノードは,他のノードにハートビートを送り,投票の終了を知らせる. • 同時に複数のCandidateが起こりうるし,複数のtermが存在しうる.無限に投票を繰り返す可能性がある. • これを解決するのが,randomized timeout.
  • 12. 14.4 Raft: Randomized Timeout • RaftはCandidateが同時に起こって投票が無限に継続するのを防ぐため,150-300ms の選挙タイ ムアウトを各サーバにランダムに割り振る. • タイムアウト中は,candidateになれない. • 投票が割れても,最速でタイムアウトを抜けるサーバが次のCandidateになり,他のサーバが タイムアウト中に RequestVote RPCを発行できるので,優先権がついた形になり,無限に投 票を繰り返す可能性が下がる. • もともとはrankingにしようとしていたが,availabilityの問題からretry形式にした. Raft uses randomized election timeouts to ensure that split votes are rare and that they are resolved quickly. To prevent split votes in the fi rst place, election timeouts are chosen randomly from a fi xed interval (e.g., 150–300ms).
  • 13. • タイムアウトの時間設定によって,リーダ不在の時間が変化す る,という実験. • 上図: small amount randomization • 下図: high amount randomization タイムアウトの時間が同じ(150ms-150ms) の場合,80%程度のケー スで100000ms (1分半以上) リーダ選出にかかることになる. リーダ不在の時間だけを見ると12-24ms が一番良さそうだ が・・・? > However, lowering the timeouts beyond this point violates Raft’s timing requirement: leaders have di ffi culty broadcasting heartbeats before other servers start new elections. This can cause unnecessary leader changes and lower overall system availability. We recommend using a conservative election timeout such as 150– 300ms; such timeouts are unlikely to cause unnecessary leader changes and will still provide good availability. リーダが細かく切り替わっていくだけで,リクエストを処理できて はいない,ということ?
  • 14. Raft: AppendEntries RPC • Leaderが決定している間は,クライアントからの要求を処理できる. 1. どのノードも,クライアントからの要求をLeaderに転送する 2. Leaderのローカルログにエントリを追記する 3. Leaderから全フォロワーにAppendEntries RPCを送信 4. 過半数のレスポンスが得られたらCommitted マークをLeaderのログに付ける 5. クライアントにCommittedを応答する. • この後でも,全てのフォロワーからレスポンスが得られるまで,無制限に再送信する. 6. Committed マークが付いたことをFollowerに知らせる (AppendEntries RPCを再送).
  • 15. 14.4 Raft: Log Matching Property • 前者: ログエントリのインデックスと任期が同じならば,必ず同じ操作 • 後者: そのようなentriesがあるならば,それ以前のログも全て同じ. Raft はこの Log Matching Propertyを提供している.これによって,一貫性を維持するための処理が簡単かつ理解しやすくなる. # 例えば,一定期間sleep/faultしていたとしても,”index 3のitemはterm 4 のもの” という AppendEntries RPCを受け取っただけで,自分の持っ ているエントリに不足がないか判断できる A. index 3, term 4 のログを持っている => 一定時間死んでいたけど,ログはすべて正しいものを持っている B. Index 1 までしか持ってない! => 無限再送される AppendEntries RPCを待てば,いつか う. C. Index 3は term 4ではない => サーバ構成が変更されたことが検出できる. • If two entries in different logs have the same index and term, then they store the same command. • If two entries in different logs have the same index and term, then the logs are identical in all preceding entries.
  • 16. • Raftでは,followerのcrashはログに影響を与えないが, Leaderのcrashによっていくつかのシナリオがありうる. (a-b): ログが足りない. (c-d): リーダにとって未コミットのエントリを持っている. (e-f): ログが足りない & 未コミットもある. すべての場合に対処できるよう,リーダーは,常に以下を行 う • 全てのfollowerからnextIndex[]を収集する.[10, 5, 11, 13…] • 自分のnextIndexを最新とする. • AppendEntries RPCを使ってLeaderとの間でLog と Term が一致するエントリまでnextIndexをデクリメントさせてい く. • nextIndex がLeaderと一致するまでAppendEntriesを行う.
  • 17. 14.4 Raft: Committing Entries From Previous Terms • AppendEntries RPCで過半数にログを複製したが,committedと通知する前に Leaderがcrashした場合,新しいLeaderはこれをcommittedだと判断できる. • 過半数にログを複製してあると,そのログを持っているノードしか次の選挙に勝て ない.そして,選挙に勝ったleaderのローカルログはcommittedだとみなされる. a. S1 が 2台に term 2を複製,そしてcrash b. S5 が term 3 のleaderに,そしてcrash c. S1 が復帰して新たなterm 2 を過半数に送付できた場 合,過半数が取れているので,term 3 を持っている ノード (S5) は選挙に勝てない.必ず (e) になる d. 逆に, term 3 が先に過半数に送付できた場合,選挙に 勝つので, term 2 は棄却される
  • 18. 14.4 Raft: Cluster Membership Changes • サーバ構成をオンラインで変更すると,選挙やログ複製の処理も一貫性を失う. • サーバ構成をアトミックに切り替えることは不可能なため. • 例えば,2つのリーダが同じtermに同居する,ということもありえてしまう. • Raftはオンラインでサーバ構成を変更できるよう, joint consensus アプローチを作った.
  • 19. 14.4 Raft: Joint Consensus • Raftでは,構成を変更するという処理を,ログエントリとして扱う. • は旧構成. は新構成. • は,旧構成の過半数と新構成の過半数,両方を使う • 構成変更のために,まず をコミットする. • その次に をコミットする. • に自分が存在しないノードは, のAppendEntries RPC を見たら,即シャットダウンできる • エントリがcommitされているか否かに依らず,持っている最新のエン トリを使う. • がcommitされていなくとも, を使う. • を使っているleaderがいる => 既に はコミット済み • => 単独でコミットできるログは存在しない => 安全 Cold Cnew Cold,new Cold,new Cnew Cnew Cnew Cnew Cnew Cnew Cold,new Cold
  • 20. 14.4 Raft: Joint Consensus • いくつかの問題/最適化/細かいアプローチがある. • 新規に追加されたノードは,これまでのログを全て反映しきるまで投票に参加できないので,足を引っ張る ことになる.そのため,”non-voting members” になってログだけを受け取ることができる. • に自分が含まれていないリーダは, がコミットされるまでは動き続ける. • に自分が含まれていないノードは, AppendEntries RPC (heartbeat) を受け取れないため,タイムアウ トが発生したとみなして他のサーバに RequestVote を行ってしまう. • これに対処するため,各ノードは,現在のリーダから指定されたタイムアウト時間がすぎるまでは, RequestVote RPCを棄却する. • # この「タイムアウト時間の指定」がどこで行われるのかわからない. AppendEntries RPC? Cnew Cnew Cnew
  • 21. 14.4 Raft: Misc • ログが単調増加するため,スナップショットを使う. • リーダの持つログは常に最新なので,リーダに作成させるのが簡単. • Raft のゴールは Linearizable & Exactly-Once. しかしcrashした場合など,何回か同じクライアントの命令がステート マシンに対して実行されうる. • クライアントの命令にserial numberを割り振って,ステートマシンに記録しておけばOK. • Read-only の命令はログを追加しないのでフォロワーが即実行できる? -> できない • リーダ以外,最新のデータを持っている保証はない • そして,リーダですらも知らないうちに新しい任期のリーダが誕生している可能性がある • これに対処するために,Read-only 命令であっても書込みと同様に扱う. no-op 命令を含むログとしてコミット.
  • 23. 14.5 ビザンチン合意 • これまでの合意アルゴリズムはすべて非ビザンチン障害が前提. • 非ビザンチン障害を前提にすると,参加ノードの数やコミットまでのRTTを減らせる. • ビザンチン障害を前提にすると,色々と難しい. • 悪意ある振る舞い,バグ,設定ミス,ハードウェア異常,データの破損など • あるメッセージが正しいかどうかについて検証するため,クォラム内の各ノードが相互 通信する必要があり, のメッセージが必要になる. • この章では, Practical Byzantine Fault Tolerance (PBFT) について議論する. N2
  • 24. 14.5 PBFT • PBFTの前提: • Independent node failures: 障害は個別に発生する.システム全体が乗っ取られること はない • Weak synchrony: 障害が発生することはあるが,無限にではなく,いつかは復旧される • Encrypted messages: ノード間の通信はすべて暗号化される.これによってメッセージ の偽造を防げる…が,障害のあるノードは結局秘密 を漏洩してしまう可能性があるの で,暗号化されているからといってメッセージが無制限に信頼できるわけではない.
  • 25. 14.5.1 PBFTアルゴリズム • PBFTがsafetyとlivenessを満たすために許容する障害レプリカの数は, • nは参加ノード数.したがって,f の障害ノード数を許容するには 必要. • クラスタ構成の中で,PBFTは views という概念を使う.各viewにおいて,以下が存在する • View: ID v をもつ.primaryで障害が発生すると変更される. • Primary: v % n のノードがこう呼ばれる.クライアントの要求を処理する. • Backup: primaryからブロードキャストされる要求を実行し,クライアントにレスポンス. • f+1 のレプリカから同じ結果が応答されたら,クライアントはコミットとみなせる. (n − 1)/3 n = 3f + 1
  • 26. 14.5.1 PBFTアルゴリズム • 以下がPBFTのプロトコルの流れ. • Primaryがクライアントのリクエストを受け取る. • Pre-Prepare phase: • primaryから{v, n, payload, digest(payload)} をブロードキャスト.nは単調増加するシーケンス番号. digestはデジタル署名を行う. • backupは,自身のviewが v と一致している digestの計算が一致する際,メッセージを受け入れる. • Prepare phase: • Backupは,Prepare メッセージ {v, n, digest(payload), i} をブロードキャスト. i はレプリカのユニーク番号. • 同じ Prepare メッセージを 2f 回,異なるbackupから受け取った場合にのみ Prepare phaseを抜ける. • Commit phase: • Backupは,このメッセージについてのCommit メッセージを 2f + 1 のノードから収集したらコミットをクライアントに返す. • クライアントは f+1 のノードからCommitを返却してもらったら,コミットと判断できる
  • 27. 14.5.1 PBFTアルゴリズム: 正常系 Figure 1: Normal Case Operation • PBFTでは,フェーズの間に必ず,各ノードが 2f + 1 のメッセージをそれぞれ収集する.そしてdigestをチェックするた め,不正なメッセージは防止できる. • 上図は primary = 0, f=1. P3 で障害が発生したため,応答を返さなくなっている.しかし,prepare -> commit で 各ノー ドが 2f のprepare を収集しており,commitも 2f +1を収集しているため,正常に続行できる. • Primaryに障害が発生した際は “view changes” というプロトコルが走り,primaryが交代する.
  • 28. 14.5.2 リカバリとチェックポイント • 各レプリカは,メッセージを永続化する. • f+1 のノードで命令が実行されるまで保持しておく必要がある. • メッセージを転送すれば,NW分断の後でもリカバリが可能・・・だが,そのメッセージが正しいものであることを保証し なければならない. • 各メッセージを反映して処理を進めながら,digestを再検証していけばよい.が,コストが高すぎる. • そこで,定期的に stable checkpoint をとる. • 最新のシーケンス番号 n と,現在の状態に対するdigest をブロードキャストする. • 2f+1 のレプリカが正しいと応答してきた場合,チェックポイントが取れている証左になる. n 以下のidのメッセージをすべ て破棄できる. • # チェックポイントは全レプリカで共通の断片ではなく,各ノードが各自に勝手に行う.
  • 29. 14.5.1 PBFTアルゴリズム: 異常系 • Primaryが動作していない,など,backupが異常の疑いを検出した際,view changes というプロトコルが走る. • それ以降のメッセージへの応答を停止し,自分がprimaryになろうとする. • viewの変更 { v+1, n, C, P, i} をbroadcastする.n は 自身が持つ最後の チェックポイントのメッセージ番号.Cはそのチェックポイントに応答し た2f+1 のノードのメッセージ集合.Pはまだチェックポイントに含まれて いないリクエストの集合. •
  • 30. 14.5.2 PBFT summary • PBFTは,敵意が含まれる可能性のあるネットワークで利用するもの. • ビザンチン障害耐性を持つプロトコルは,メッセージ数が増大するという欠点がある.PBFTも, (primaryを立てているのにも関わらず) ブロードキャストを多用してしまっている. • 参加ノードの台数 N や 故障許容ノードの数 f というパラメータを全レプリカで共有しなければなら ない.これは前述したweak synchrony があるから許されている.パブリックブロックチェーン等の 世界ではその点で評価されていない(と思う). • > 大半の場合は,ノード間の通信を認証して暗号化すれば十分ですが,システムのパーツ間 に信頼性がない場合には,PBFTに類似したアルゴリズムを導入しなければなりません.
  • 31. 14.6 まとめ • Multi-paxos: proposerが継続する.複数の値についてreplicationできる. • Fast paxos: fast ラウンドが存在し,メッセージの数が削減されている. • EPaxos:メッセージ間の依存関係を解決し,イベントの順序が確立できる. • Flexible Paxos: クォラムの要件を緩和する. • Raft: 強いリーダシップがあり,Paxosの各要素がdecompositionされ,理解しやすい. • PBFT: 敵意が含まれる(HW故障なども含む) 環境で安全に合意できる.
  • 32. References [1] Diego Ongaro, John K. Ousterhout: In Search of an Understandable Consensus Algorithm. USENIX Annual Technical Conference 2014: 305-319 [2] https://raft.github.io/slides/linkedin2014.pptx [3] Miguel Castro, Barbara Liskov (1999) Practical Byzantine Fault Tolerance