運行 3000 次都不出錯的 MIT 6.824 Raft 實驗
前幾天在分布式系統(tǒng)交流群里,小伙伴們都在討論 6.824 的 raft 實驗批量測試 2000 次以上總會出錯,錯誤出在 Figure8Unreliable 和 UnreliableChurn2 這兩個測試。我自己其實也遇到了這個問題,這里記錄下我自己的解決思路。
能到這步,首先默認你的程序已經(jīng)沒有大的問題,只是在上千次的測試中會有選舉不出來(活鎖問題)或提交的日志沖突問題。如果連單次測試都還過不去,請先移步《【MIT 6.824】學習筆記 5: 2021 Raft 實驗實現(xiàn)細節(jié)》
上面兩個測試說白了,就是把網(wǎng)絡搞得很亂,寫一堆日志,然后給你 10 秒時間,沒選出新的 Leader 就會出錯。主要有兩種錯誤:failed to reach agreement 或者 apply error
這兩個問題分別用下面兩種思路解決。
選舉超時不能隨便重置
如果仔細閱讀過 Students' Guide to Raft,其實里面很清楚寫著,選舉超時時間只能在下面三種情況下重置:
- 收到現(xiàn)任 Leader 的心跳請求,如果 AppendEntries 請求參數(shù)的任期是過期的(args.Term < currentTerm),不能重置;
- 節(jié)點開始了一次選舉;
- 節(jié)點投票給了別的節(jié)點(沒投的話也不能重置);
原文:
you should only restart your election timer if a) you get an AppendEntries RPC from the current leader (i.e., if the term in the AppendEntries arguments is outdated, you should not reset your timer); b) you are starting an election; or c) you grant a vote to another peer.
這個問題其實很容易理解,主要容易錯在,代碼改著改著,就會不小心搞錯了選舉時間重置的位置,然后給后面的排查埋下了坑。
檢查一下你是否胡亂重置了這個時間,我和群里另一位小伙伴的問題就出現(xiàn)在第三種情況。
正確處理 rpc 響應
處理 rpc 響應的時候也要小心,收到 rpc 響應的時候,如果 currentTerm != args.Term 了,這次 rpc 就要丟掉不能用了。
當然,如果節(jié)點角色已經(jīng)變了,那也要忽略掉這次 rpc 響應。
總結(jié)
調(diào)試這個問題主要是要細心,關注細節(jié),多讀幾遍:https://thesquareplanet.com/blog/students-guide-to-raft/
進行批量測試的腳本在這里:https://gist.github.com/jonhoo/f686cacb4b9fe716d5aa
使用方法是:
- ./go-test-many.sh 測試次數(shù) 并行數(shù)(默認是 CPU 個數(shù)) 哪個測試
例如要測試 2C 這個測試 2000 次,并行 8 個測試。
- ./go-test-many.sh 2000 8 2C
又比如單獨測試 TestFigure8Unreliable2C 2000 次。
- ./go-test-many.sh 2000 8 TestFigure8Unreliable2C
本文轉(zhuǎn)載自微信公眾號「多顆糖」,可以通過以下二維碼關注。轉(zhuǎn)載本文請聯(lián)系多顆糖公眾號。