寫在前面
最近更新的可能會比較慢,因爲分佈式系統這個部分到目前還是爲愛發電。上個月是在開學考試的階段,接下來可能會受一些項目或者學習課程安排上的影響,不過這個內容會堅持下去的。
lab2A的內容主要是關於Raft中server選舉的實現,論文中的Figure2以僞代碼的格式給出了很多較爲詳盡的解釋,沒有出大問題的話我打算跟着Figure2的框架來進行操作。lab2A在分析過程中看了中文的翻譯解釋版(英語水平有點爛),po一下。
Figure 2:
整體架構
Raft結構體是每一個server都具備一個的,作爲狀態機的存在。每一個server就本質上並無差距,只是其所處的狀態機的狀態不同。
- 我們定義了三種狀態:Follower, Candidate, Leader。
- RPC通信的方式定義兩種:AppendEntries RPC, RequestVote RPC。(採用sendXXX()調用其他server的XXX()方法,例如sendAppendEntries_RPC)
- 定義時鐘檢查Timer:electionTimer, heartbeatTimer
論文中的Figure 4較爲形象地表示了這個過程,Figure 5則是從時間的維度上看的:
狀態對應的產生事件
-
Follower:
處理AppendEntries RPC
處理RequestVote RPC
electionTimer
超時 -
Candidate
處理AppendEntries RPC
處理RequestVote RPC
electionTimer
超時
發起投票sendRequestVote
-
Leader
處理AppendEntries RPC
處理RequestVote RPC
electionTimer
超時
heartbeatTimer
超時
發送更新心跳包sendAppendEntries
衝突避免
AppendEntries RPC
和RequestVote RPC
是處在一個新go routine之中的,爲了防止同時調用產生互斥,用mutex鎖一下保平安。
對於electionTimer
和heartbeatTimer
,在生成Raft實例的時候多生成一個go routine,之後我們採用選擇切換的方式處理timer的timeout定時事件,並行調用sendAppendEntries
和sendRequestVote
。
Access
Accessed in 2023/10/6 15:30(UTC +8:00)
Test (2A): initial election ...
... Passed -- 3.1 3 46 5618 0
Test (2A): election after network failure ...
... Passed -- 4.5 3 106 8244 0
Test (2A): multiple elections ...
... Passed -- 5.4 7 534 43952 0
PASS
ok 6.5840/raft 12.963s
改動部分
結構體改動部分:Raft, RequestVoteArgs, RequestVoteReply, AppendEntriesArgs, AppendEntriesReply
新增函數:convertTo(轉換狀態), AppendEntries, sendAppendEntries(仿照Request...), broadcastHeartbeat(要鎖), startElection(要鎖), randTimeDuration(raft不等要求)
之後就是在文件raft.go
中代碼有提示需要在加"Your code here (2A)"的地方加了,都是對於原有的函數功能的實現。