Raft選舉機制解析


前言

Etcd是一個強一致性的分布式架構,即CP,所有請求必須經過leader節點,先由leader節點向follower節點發送日志同步消息,經過二階段提交最終將數據應用到狀態機。因此集群在初始化時必須有個選主的過程。

 

Etcd節點有以下三種角色:

 

Follower

集群初始化時,都是follower節點,follower節點負責以下幾個功能:

  • 接收leader節點的日志同步請求。
  • 接收競選節點的投票請求。

 

Candidate

每個follower節點都有一個超時時間,當過了這個超時時間一直沒有收到leader節點的心跳,則會成為競選節點,向其他節點發起投票請求。

 

Leader

所有的讀寫請求都需要經過leader節點,當競選節點競選成功后,會將角色置為leader,follower節點會從該節點同步最新的日志,以保證整個集群的一致性。

 

選舉流程

  1. 節點超過超時時間,進入競選狀態,會向其他節點發起投票請求。

  2. follower節點收到投票請求后會根據投票規則決定是否投票,並將投票結果(贊成/反對)返回給競選節點。

  3. 競選節點收到投票反饋后,會統計投票,如果有過半節點同意則變為leader,並告知其他節點,否則重新變為Follower角色。

 

投票規則

競選節點發起投票請求時,會向所有follower節點發送自己日志的任期和索引號, follower節點收到后會比較自己的日志是否比競選節點的新,先比較任期,任期大的的日志最新,如果任期一樣,則比較索引號,索引號大的日志最新

 

預選舉

raft算法中,競選節點在選舉之前會先把自己的任期加1,然后發起投票請求,那如果此時出現了網絡分區,如下圖所示:

 

 

當Follower_2在達到electionTimeout后還沒收到leader的心跳,會觸發選舉,並轉為Candidate。每次發起選舉時,會把Term加1。由於網絡隔離,它既不會被選成Leader,也不會收到Leader的消息,而是會一直不斷地發起選舉。Term會不斷增大,這會產生什么問題呢?

 

在網絡恢復之后,因為Follower_2還是處於競選中,它這會把它的Term傳播到集群的其他節點,其他節點認為自己的日志比它舊,就肯定會選它為leader,,但事實上Follower_2節點的日志可能會落后其他節點很多了,顯然是不應該成為leader節點的。那如何避免這種情況發生呢?

 

raft算法對競選機制進行了改良,就是所謂的預選舉。Candidate首先要確認自己要能贏得集群中大多數節點的投票,這樣才會把自己的term增加,然后發起正式的投票,如果預選舉不通過,則該節點的term不會增加。關鍵邏輯如下:

 

// becomePreCandidate()方法
func (r *raft) becomePreCandidate() {
    if r.state == StateLeader {
        panic("invalid transition [leader -> pre-candidate]")
    }
    r.step = stepCandidate
    r.prs.ResetVotes()
    r.tick = r.tickElection
    r.lead = None
    r.state = StatePreCandidate
    r.logger.Infof("%x became pre-candidate at term %d", r.id, r.Term)
}


//becomeCandidate()方法
func (r *raft) becomeCandidate() {
    // TODO(xiangli) remove the panic when the raft implementation is stable
    if r.state == StateLeader {
        panic("invalid transition [leader -> candidate]")
    }
    r.step = stepCandidate
    r.reset(r.Term + 1)    //一旦變為競選角色,term立馬加1
    r.tick = r.tickElection
    r.Vote = r.id
    r.state = StateCandidate
    r.logger.Infof("%x became candidate at term %d", r.id, r.Term)
}
View Code

 

可以看到預選舉時Term並不會增加,而是等進入正式選舉時Term才會增加。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM