動機
raft有一些優化,這邊記錄一些 主要出自raft作者的博論
Batching
AppendEntries可以一次累積多一點log再丟出去,把latency往下壓
Pipelining
因為raft的log一定是遞增,所以raft實際上可以根據任何順序丟log出去,也就是說不用依據follower實際上的最後一位去丟 直接看netxIndex多少去丟就好,甚至還可以實作reorder
prevote
有人經歷network partiotion,這樣他的log一定不會是最新的(不會是leader) 但是,他的term會異常大!!
這樣其他人會因為看到這超大的term,被迫變成follower,但因為log的緣故也絕對不會是他當leader,這樣其實很浪費。 所以,可以多一個階段,prevote,類似zab,先投出一個leader,之後sync log才把epoch(term)推上去,但這裡是先丟自己的log出去,問其他人要不要投,有過半就開啟正式的投票。
read index
之前lab3與4的read都要過raft,這真的很慢。
所以利用leader的log一定有所有commit log的特性。
- 先丟no-op (確認log與把前面的都commit)
- 記下當下的index為readIndex
- 等收到過半的reply(其實是要等lastApplied更新)
- 之後只要read的指令的index沒有超過readIndex就可以直接回
follower就可以去問leader當前的readIndex,之後等lastApplied大於這個readIndex,就可以直接回了
lease read
有沒有辦法不丟no-op只透過heartbeat更新?
如果能保證每台機器的時間都是一致的
收到過半的heartbeat,當成直到election timer啟動前都是leader(所以說要保證時間一致,想想如果leader被pause的話…)
只要確認自己是leader且log有同步(過了appendEntries),就可以直接回
發log同時persist
raft是看過半來決定要不要commit,所以
- 有過,先寫到disk就賺到
- 沒過,沒差之後會被其他appenEntries修掉
profile, hdd效能, test
這邊是列出dragonboat作者的文章,比起上面的優化,這邊都是屬於實作上的細節,值得一看。
从共识算法开谈 - 硬盘性能的最大几个误解 百亿次的锤炼 - 带逛Dragonboat的各类测试 <= 其實6.824的lab3,4都有用到!! 大规模Go项目几乎必踏的几个坑 - Dragonboat为例 Go系统性能绕坑工具与方法 - 基于实例的带逛 让Raft变快100倍 - Dragonboat的写优化