Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
hashicorp_raftからraftを学ぶ
Search
t10471
June 15, 2023
Technology
0
940
hashicorp_raftからraftを学ぶ
raftの論文の解説とhashicorp/raftの使い方について解説します。
t10471
June 15, 2023
Tweet
Share
More Decks by t10471
See All by t10471
EOSにPull Requestを出してマージされた話
t10471
1
700
分散台帳・暗号通貨とRust ブロックチェーンをRustで作ってる話
t10471
2
1.4k
Kubernetesの ダークカナリアリリースツールを作った話
t10471
0
950
Kubernetes・GCPを使った チャットボットサービスの 機械学習部分の話
t10471
0
170
型についてちょっと考える
t10471
1
310
Other Decks in Technology
See All in Technology
TypeScript 上達の道
ysknsid25
3
380
M365アカウント侵害時の初動対応
lhazy
6
4.4k
Bliki (ja), and the Cathedral, and the Bazaar
koic
8
1.3k
Semantic Machine Intelligence for Vision, Language, and Actions
keio_smilab
PRO
2
380
自分がLinc’wellで提供しているプロダクトを理解するためにやったこと
murabayashi
1
160
Expertise as a Service via MCP
yodakeisuke
1
140
エンジニアリングマネージャー“お悩み相談”パネルセッション
ar_tama
1
640
組織内、組織間の資産保護に必要なアイデンティティ基盤と関連技術の最新動向
fujie
0
500
怖くない!GritQLでBiomeプラグインを作ろうよ
pal4de
1
120
Introduction to Sansan for Engineers / エンジニア向け会社紹介
sansan33
PRO
5
39k
TROCCO今昔
gtnao
0
210
Jitera Company Deck / JP
jitera
0
140
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
134
9.4k
Art, The Web, and Tiny UX
lynnandtonic
301
21k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Unsuck your backbone
ammeep
671
58k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Into the Great Unknown - MozCon
thekraken
40
1.9k
The World Runs on Bad Software
bkeepers
PRO
70
11k
Making Projects Easy
brettharned
116
6.3k
How STYLIGHT went responsive
nonsquared
100
5.6k
Designing for humans not robots
tammielis
253
25k
Speed Design
sergeychernyshev
32
1k
It's Worth the Effort
3n
185
28k
Transcript
1 hashicorp/raftからraftを学ぶ mercari.go #22 @toshinao
2 • twitter ◦ toshinao • Backend Engineer at Mercoin
◦ 主に外部システム連携を担当 自己紹介
3 • https://www.oreilly.co.jp/books/97848731199 77/ • Go言語による分散サービスの中でraftを使ったシ ステムのハンズオンが記載されている • hashicorp/raftを使った分散ログ保存サービスの コードが載っている
raftについて調べたきっかけ
4 • ログや設定を保存するための分散合意アルゴリズム • etcd(KVS)やcunsul(サービスディスカバリー)の中で使わ れている • Leaderの権限が強い ◦ シンプルで分かりやすいメカニズムを目指して作られた
◦ clientの応答は全てLeaderが返す(と論文には書かれている) ◦ ログの送信(レプリケーション)はLeaderから送る ◦ 過半数に書き込みが成功すると確定したことになる raftについて
5 • 論文は2つある ◦ 最初に博論として書かれた ▪ https://github.com/ongardie/dissertation#readme ◦ よく読まれている論文は元の論文からコンセンサスアルゴリズム部 分を抽出している
▪ https://raft.github.io/raft.pdf • 博論には下記について詳細に書かれている ◦ 構成変更 ◦ ログのコンパクション ◦ clientとのやり取り 論文
6 • ログはどのノードも同じ状態になるような仕組み ◦ 有限状態機械(Finite State Machine; FSM)として同じ順序でロ グを適応することで実現している •
Leaderからheartbeatを送る ◦ leaderから一定期間heartbeatが送られないと選挙が始まる • 論理時計を持つことでクラスターの一貫性を保つ ◦ hashicorp/raftではlamport clockを使用している ◦ term(Leaderの期間)、index(単調増加する値)を保存・送信する 特徴
7 • Followerから始まる • 選挙が始まると(timeoutを検知すると)Candidateになる • 選挙で選ばれるとLeaderになる • Leaderの時に自分より大きいtermのログが届くとFollower になる
サーバーの状態
8 • コンセンサス ◦ AppendEntries RPC ▪ ログの追加 ▪ heartbeat(空で送るとheartbeatになる)
◦ RequestVote RPC ▪ 選挙 • 構成変更(博論にだけ載っている) ◦ AddServer RPC ▪ 新しいサーバー追加 ◦ RemoveServer RPC ▪ サーバーの削除 論文に載っているRPC1
9 • Snapshotの連携(博論にだけ載っている) ◦ InstallSnapshot RPC ▪ ログの連携が遅いフォロワーに対してSnapshotを送る • クライアント(博論にだけ載っている)
◦ ClientRequest RPC ▪ PRCのリクエスト ◦ ClientQuery RPC ▪ Read Onlyのリクエスト ◦ RegisterClient RPC ▪ client毎にidを発行する(重複リクエストを識別出来るようにす るため) 論文に載っているRPC2
10 • Leaderからのheartbeatが途切れたら選挙がはじまる • FollowerからCandidateに変更 • 立候補はランダムな時間をおいてからリクエストする ◦ 立候補とはRequestVote RPCを他のサーバーに送ること
◦ 票が割れてLeaderが決まらないケースを減らす • RequestVote RPC受信側は自分の持っているterm、indexの方が 大きい場合、投票しない 選挙
11 • Leaderが変わるとtermが変わる • Leaderが決まらなかった場合、termが変わる ◦ 票が割れた場合など ◦ Lederがいないtermが存在する termと選挙の関係
12 // 下記の関数でraftインスタンスを生成・起動 func NewRaft(*Config, FSM, LogStore, StableStore, SnapshotStore,Transport) (
*Raft, error) // FSMは下記のメソッドを実装している必要がある type FSM interface { Apply(*Log) interface{} Snapshot() (FSMSnapshot, error) Restore(snapshot io.ReadCloser) error } // LogStoreはAppendEntries RPCで追加するログの保存 // StableStoreは設定を保存 // LogStoreとStableStoreで使えるraft-mdbやraft-boltdbがある // SnapshotStoreはLogStoreのSpanpshot // Transportはサーバー間で通信する為のロジック hashicorp/raftの使い方・生成
13 // Leaderとして起動(BootstrapClusterしないサーバーはFollowerとして起動) func (r *Raft) BootstrapCluster(configuration Configuration) Future //
Logの追加 func (r *Raft) Apply(cmd []byte, timeout time.Duration) ApplyFuture // clusterに参加 func (r *Raft) AddVoter(id ServerID, address ServerAddress, prevIndex uint64, timeout time.Duration) IndexFuture // clusterから抜ける func (r *Raft) RemoveServer(id ServerID, prevIndex uint64, timeout time.Duration) IndexFuture // Leaderを他のサーバーに委譲する func (r *Raft) LeadershipTransfer() Future // restoreを強制的に呼ぶ raft.Restore(meta *SnapshotMeta, reader io.Reader, timeout time.Duration) Leaderで呼ぶ必要があるメソッド
14 // Leaderサーバーのアドレスを取得 func (r *Raft) Leader() ServerAddress // 設定の取得
func (r *Raft) GetConfiguration() ConfigurationFuture // 自サーバーがどの状態(Leader、Follower、Candidate)か取得 func (r *Raft) State() RaftState // snapshotを強制的に呼ぶ func (r *Raft) Snapshot() SnapshotFuture // サーバーをshutdownするときに呼ぶ func (r *Raft) Shutdown() Future Leader以外でも良いメソッド
15 • AppendEntries ◦ logをFollowerに送る ◦ 構成変更もAppendEntriesで送られる • RequestVote ◦
Leaderになるときに他のサーバーに送る ▪ last_log_indexやlast_log_termも送る ◦ responseのGrantedをtrueで返すと投票したことになる • TimeoutNow ◦ Leaderを委譲するサーバーに選挙開始を伝える • InstallSnapshot ◦ コンパクション済みでAppendEntriesで遅れない場合にspanshotを送る hashicorp/raftの内部API
16 • 論文と実装ではことなることがある • Client APIは存在しない ◦ Leader以外で更新系処理を実行するとエラーになる ◦ Leaderが誰か把握している必要がある
◦ 取得系の処理はLeader以外が返しても良い • Configurationの更新もAppendEntriesで伝える ◦ AddServer RPC やRemoveServer RPCは存在しない • TimeoutNowというAPIが存在する ◦ Leaderの委譲時に使う ▪ 移譲先が早くRequestVoteを送るために使用する まとめ