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