Raft/Leader-Election
選舉發生
若Follower在指定超時時間內沒有收到Leader發送的HeartBeat,則節點狀態由Follower轉爲Candidate.
並開始進行選舉.算法
投票
- CurrentTerm增長1(表示進入下一任期)
- 向自身節點投票
- 設定隨機超時時間(ElectionTimeOut -- 2*ElectionTimeOut)
- 向集羣中每個節點發送VoteRequest
- 參數 :
- CurrentTerm : 當前Server CurrentTerm值
- Name : 當前Server名稱
- LastLogIndex : Log中最新Index值
- LastLogTerm : Log中最新Term值
處理投票請求
- 判斷請求參數Term :
- 若是Req.Term小於Self.Term,拒絕請求併發送Self.Term
- 若是Req.Term大於Self.Term,更新Self.Term並將節點狀態轉爲Follower
- 若是Req.Term等於Self.Term且已經接受過投票,拒絕請求併發送Self.Term
- 判斷LastLogIndex,LastLogTerm :
- 若是Self.LastLogIndex 或者 Self.LastLogTerm 大於 Req中相應的值,則拒絕該請求
- 成功投票:
- 流程分析 :
- 判斷Term :
- Term爲Raft算法中的邏輯時鐘.做爲某些在同一週期內只能發生一次的行爲的判斷依據.
- 若是Req.Term大於Self.Term,說明本節點週期落後於系統(新加入集羣,Crash後恢復,落後節點等狀況)
- 若是Req.Term小於Self.Term,說明請求節點週期落後於系統,則拒絕請求
- 在相同Term週期中,投票行爲只能發生一次
- 判斷LastLogIndex,LastLogTerm :
- 拒絕投票給Log落後於本節點的節點請求,從而保證選出的Leader擁有最完整的數據
- 由於提交數據須要得到大多數節點的認可,因此落後節點的投票請求會被大多數節點所拒絕,從而保證了Leader必定擁有完整數據.
選舉結束
- 得到大多數節點贊成 : 節點狀態從Candidate變爲Leader
- 收到AppendEntriesRequest(心跳) : 若是Req.CurrentTerm大於等於Self.CurrentTerm.則節點變爲Follower,退出選舉.
- 超時 : Self.CurrentTerm增長一.從新開始選舉