Raft算法之選舉篇


前面我們介紹了Raft算法,接下來會分篇講述每一個部分,今天講述選舉的細節。

 

在講述選舉之前,先介紹下Raft算法基礎。

 

一、Raft基礎

1、節點角色

在Raft中,在任意時刻,服務器節點只能是以下3個角色之一:

 

Follower(跟隨者):系統啟動時默認的角色,一般來說不參與客戶端讀、寫請求,接受Leader發送過來的心跳追加日志,在Leader掛了之后轉變為Candidate;

 

Candidate(候選人):如果當前沒有Leader,Follower就轉變為這個角色,這個角色會向其它節點發起投票請求,如果多數節點同意投票,則晉升為Leader;

 

Leader(領導人):接受客戶端的讀、寫請求,協調整個日志的持久化和推進;

 

下面講節點角色時統一用英文描述。

 

2、節點角色狀態遷移圖

 

 

系統啟動時,大家都是Follower,然后啟動定時器,如果在指定時間沒有收到Leader的心跳,則將自己變成Candidate,然后向其它成員發起投票請求,如果收到過半以上成員的投票則Candidate晉升為Leader;

 

Leader發送心跳給其它成員時如果收到的響應中term比自己的大,則退化成Follower;

 

3、邏輯時鍾(term)

選舉過程有個term參數,這個參數就是邏輯時鍾,這是一個整數,全局遞增;Raft 把時間分割成任意長度的任期,用term來標識每一屆leader的任期,這樣可以保證在一個任期內只有一個Leader。

 

邏輯時鍾規則如下:

Candidate發起選舉時就將自己的term加1,然后發起投票請求;

收到投票請求的節點比較請求的term和自己的term,如果請求的term比自己的大,則更新自己的term;

這樣在即使每個節點的時間不一樣的情況下也可以推進邏輯時鍾;

 

 

4、狀態

狀態 所有服務器上持久存在的
currentTerm 服務器最后一次知道的任期號(初始化為 0,持續遞增)
votedFor 在當前獲得選票的候選人的 Id
log[] 日志條目集;每一個條目包含一個用戶狀態機執行的指令,和收到時的任期號

上面的狀態是所有節點都要保存的,並且要持久化的,即每次變更馬上要寫入磁盤。

 

 

狀態 所有服務器上經常變的
commitIndex 已知的最大的已經被提交的日志條目的索引值
lastApplied 最后被應用到狀態機的日志條目索引值(初始化為 0,持續遞增)

上面的狀態是保存在內在中,每次重啟后都0開始,即不需要持久化到磁盤上。

 

狀態 在領導人里經常改變的 (選舉后重新初始化)
nextIndex[] 對於每一個服務器,需要發送給他的下一個日志條目的索引值(初始化為領導人最后索引值加一)
matchIndex[] 對於每一個服務器,已經復制給他的日志的最高索引值

上述只有在Leader節點才會需要保存,並且是也是保存在內存中,不需要持久化,重啟后從0開始。

 

二、領導人選舉

領導人選舉發生的條件為Follower沒收到Leader的心跳,具體場景一般如下:

1、系統啟動時

2、Leader掛了或網絡分區了

 

具體細節如下:

1、請求投票 RPC

由候選人發起

 

參數 解釋
term 候選人的任期號
candidateId 請求選票的候選人的 Id
lastLogIndex 候選人的最后日志條目的索引值
lastLogTerm 候選人最后日志條目的任期號

 

返回值

返回值 解釋
term 當前任期號,以便於候選人去更新自己的任期號
voteGranted 候選人贏得了此張選票時為真

 

接收請求投票的節點響應規則如下:

  1. 如果term < currentTerm返回 false;
  2. 如果 votedFor 為空或者為 candidateId,並且候選人的日志至少和自己一樣新,那么就投票給他;

第1條規則好理解,第2條規則前面部分是為了保證在一個任期內每個節點只投1票,前面也說過這個信息是要持久化的;

 

候選人的日志至少和自己一樣新:這里說的就比較籠統了,這里的意思是要看下各自最后1條日志,即兩者的索引號和term都對的上,我們看一個實際的例子:

 

 

 

 

上面的例子從上往下假設分別為A、B、C、D、E節點,A當前為Leader,各節點日志索引如下:

A:8

B:5

C:8

D:2

E:7

 

如果這時候A掛了,如果D最先升級為Candidate,B、C、E收到請求后都不會為D投票,拿B來說,B發現D的最后一條日志索引為2,而自己的日志索引為8,因此拒絕B的請求。

 

 

關於選舉還有其它一些規則:

1、針對Follower

如果在超過選舉超時時間的情況之前都沒有收到Leader的心跳,或者是Candidate請求投票的,就自己變成Candidate;

2、針對Candidate

開始選舉后的動作如下:自增當前的任期號(currentTerm); 給自己投票; 重置選舉超時計時器;發送請求投票的 RPC 給其他所有服務器; 
收到響應后的規則:如果接收到大多數服務器的選票,那么就變成Leader;如果接收到來自新的領導人的心跳信息,則轉變成Leader;如果選舉過程超時,再次發起一輪選舉; 

3、針對Leader

一旦成為領導人:發送空的附加日志 RPC(心跳)給其他所有的服務器;在一定的空余時間之后不停的重復發送,以阻止跟隨者超時。

 


免責聲明!

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



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