可能是你能找到的最完整最詳細(xì)的中文版的Raft算法說明博客
內(nèi)容來源都是原生的論文,可以保證內(nèi)容的可靠性杈绸,并且對論文里面的很多細(xì)節(jié)做了擴展說明
任期的概念 term
任期的概念:
- Raft 把時間分割成任意長度的任期(term)寞蚌,如圖 5 所示林螃。任期用連續(xù)的整數(shù)標(biāo)記纽竣。
- 每一段任期從一次選舉開始坠韩,一個或者多個 candidate 嘗試成為 leader 卑笨。如果一個 candidate 贏得選舉孕暇,然后他就在該任期剩下的時間里充當(dāng) leader 。在某些情況下赤兴,一次選舉無法選出 leader 妖滔。在這種情況下,這一任期會以沒有 leader 結(jié)束桶良;一個新的任期(包含一次新的選舉)會很快重新開始座舍。
- Raft 保證了在任意一個任期內(nèi),最多只有一個 leader
個人理解:
- 在raft算法中陨帆,比較誰的數(shù)據(jù)最新有2個參考指標(biāo)曲秉,任期和logIndex,任期大的節(jié)點疲牵,數(shù)據(jù)一定最新承二,任期一樣的話,就要比較該任期內(nèi)誰的MaxLogIndex最大了瑰步。引入任期的概念可以簡化數(shù)據(jù)比較的精度矢洲。
任期的作用:
不同的服務(wù)器節(jié)點觀察到的任期轉(zhuǎn)換的次數(shù)可能不同,在某些情況下缩焦,一個服務(wù)器節(jié)點可能沒有看到 leader 選舉過程或者甚至整個任期全程读虏。
任期在 Raft 算法中充當(dāng)邏輯時鐘的作用,這使得服務(wù)器節(jié)點可以發(fā)現(xiàn)一些過期的信息比如過時的 leader 袁滥。
每一個服務(wù)器節(jié)點存儲一個當(dāng)前任期號盖桥,該編號隨著時間單調(diào)遞增。
服務(wù)器之間通信的時候會交換當(dāng)前任期號题翻;
如果一個服務(wù)器的當(dāng)前任期號比其他的小揩徊,該服務(wù)器會將自己的任期號更新為較大的那個值。
如果一個 candidate 或者 leader 發(fā)現(xiàn)自己的任期號過期了嵌赠,它會立即回到 follower 狀態(tài)塑荒。(所以說老leader如果發(fā)生了網(wǎng)絡(luò)分區(qū),后來接收到新leader的心跳的時候姜挺,比拼完任期之后齿税,會自動變成follower。
如果一個節(jié)點接收到一個包含過期的任期號的請求炊豪,它會直接拒絕這個請求凌箕。
選舉的發(fā)起流程:
- 每個Node啟動的時候拧篮,初始化Role都是Follower,并且啟動計時器牵舱,超時還沒接收到消息(可以是Leader的AppendEntries RPC串绩,也可以是 Candidate的Vote RPC)
Raft集群的啟動選舉
Raft 使用一種心跳機制來觸發(fā) leader 選舉。當(dāng)服務(wù)器程序啟動時芜壁,他們都是 follower 礁凡。一個服務(wù)器節(jié)點只要能從 leader 或 candidate 處接收到有效的 RPC 就一直保持 follower 狀態(tài)。Leader 周期性地向所有 follower 發(fā)送心跳(不包含日志條目的 AppendEntries RPC)來維持自己的地位慧妄。
如果一個 follower 在一段選舉超時時間內(nèi)沒有接收到任何消息把篓,它就假設(shè)系統(tǒng)中沒有可用的 leader ,然后開始進(jìn)行選舉以選出新的 leader腰涧。選舉過程
要開始一次選舉過程韧掩,follower 先增加自己的當(dāng)前任期號并且轉(zhuǎn)換到 candidate 狀態(tài)。然后投票給自己并且并行地向集群中的其他服務(wù)器節(jié)點發(fā)送 RequestVote RPC(讓其他服務(wù)器節(jié)點投票給它)窖铡。
Candidate 會一直保持當(dāng)前狀態(tài)直到以下三件事情之一發(fā)生:
(a) 它自己贏得了這次的選舉(收到過半的投票)
(b) 其他的服務(wù)器節(jié)點成為 leader
(c) 一段時間之后沒有任何獲勝者疗锐。這些結(jié)果會在下面的章節(jié)里分別討論。
當(dāng)一個 candidate 獲得集群中過半服務(wù)器節(jié)點針對同一個任期的投票费彼,它就贏得了這次選舉并成為 leader 滑臊。
對于同一個任期,每個服務(wù)器節(jié)點只會投給一個 candidate 箍铲,按照先來先服務(wù)(first-come-first-served)的原則(注意:5.4 節(jié)在投票上增加了額外的限制)雇卷。
要求獲得過半投票的規(guī)則確保了最多只有一個 candidate 贏得此次選舉(圖 3 中的選舉安全性)。
一旦 candidate 贏得選舉颠猴,就立即成為 leader 关划。然后它會向其他的服務(wù)器節(jié)點發(fā)送心跳消息來確定自己的地位并阻止新的選舉。
在等待投票期間翘瓮,candidate 可能會收到另一個聲稱自己是 leader 的服務(wù)器節(jié)點發(fā)來的 AppendEntries RPC 贮折。
如果這個 leader 的任期號(包含在RPC中)不小于 candidate 當(dāng)前的任期號,那么 candidate 會承認(rèn)該 leader 的合法地位并回到 follower 狀態(tài)资盅。
如果 RPC 中的任期號比自己的小调榄,那么 candidate 就會拒絕這次的 RPC 并且繼續(xù)保持 candidate 狀態(tài)。
第三種可能的結(jié)果是 candidate 既沒有贏得選舉也沒有輸:如果有多個 follower 同時成為 candidate 呵扛,那么選票可能會被瓜分以至于沒有 candidate 贏得過半的投票每庆。
當(dāng)這種情況發(fā)生時,每一個候選人都會超時今穿,然后通過增加當(dāng)前任期號來開始一輪新的選舉缤灵。然而,如果沒有其他機制的話荣赶,該情況可能會無限重復(fù)凤价。
Raft 算法使用隨機選舉超時時間的方法來確保很少發(fā)生選票瓜分的情況,就算發(fā)生也能很快地解決拔创。為了阻止選票一開始就被瓜分利诺,選舉超時時間是從一個固定的區(qū)間(例如 150-300 毫秒)隨機選擇。這樣可以把服務(wù)器都分散開以至于在大多數(shù)情況下只有一個服務(wù)器會選舉超時剩燥;然后該服務(wù)器贏得選舉并在其他服務(wù)器超時之前發(fā)送心跳慢逾。同樣的機制被用來解決選票被瓜分的情況。每個 candidate 在開始一次選舉的時候會重置一個隨機的選舉超時時間灭红,然后一直等待直到選舉超時侣滩;這樣減小了在新的選舉中再次發(fā)生選票瓜分情況的可能性。9.3 節(jié)展示了該方案能夠快速地選出一個 leader 变擒。
個人理解:
選舉其實看其實PK3個指標(biāo):term君珠、LastLogIndex、lastLogTerm娇斑,至少要不比自己小才會vote給你策添,實際上這并不能保證最新的數(shù)據(jù)
因為vote RPC里面,只有l(wèi)astLogIndex和Term毫缆,可能leader里面的lastLog是未提交的狀態(tài)唯竹,但是其它follower的狀態(tài)是提交的。所以新一任leader上任之前做的第一件事就是發(fā)一個心跳苦丁,update lastCommitIndex
投票消息(候選者發(fā)起)
follow在一定時間內(nèi)未接收到leader發(fā)過來的heartbeat浸颓,超時后自己狀態(tài)成為候選者,并且向其它的所有節(jié)點發(fā)起一個投票消息
一個完整的投票消息包括4個參數(shù)
- 自己的term
- 候選者ID(自己的ID)
- lastLogIndex index of candidate’s last log entry
- lastLogTerm term of candidate’s last log entry
receiver節(jié)點:先判斷term旺拉,再判斷日志是否是最新的产上。至少任期以及日志記錄,不比自己舊蛾狗,才會投票給你蒂秘。所以過時的節(jié)點不會得到大多數(shù)的投票。
啟動投票
- 系統(tǒng)剛剛啟動淘太,所有節(jié)點的任期都是0姻僧,大家的role都是follower
- 一個啟動的節(jié)點第一個觸發(fā)未檢測到心跳超時,自增任期為1蒲牧,并且重新計時(投票開始時間)撇贺,給自己投一票,然后向所有的其它節(jié)點發(fā)起投票
- 其它節(jié)點當(dāng)前的任期都為0冰抢,且日志也沒空松嘶,肯定會投票給它,而且這些節(jié)點因為收到了candidate的投票選舉挎扰,清零自己的心跳空白等待時間翠订,未超時前不會發(fā)起投票巢音,從而避免多重投票導(dǎo)致無效投票的可能性
- 第一個發(fā)起投票的節(jié)點收到半數(shù)投票,成為leader尽超。即使投票失敼俸场(半數(shù)投票不成功)也要等到自己投票超時時間,到了超時時間之后似谁,再自增任期傲绣,發(fā)起新的一輪投票。
運行中發(fā)起投票
- 每次follower收到leader的一次HeartBeat巩踏,都會清零自己的心跳計時器秃诵,重新開始計時,如果當(dāng)前心跳計時器超時了塞琼,仍然未收到leader的心跳菠净,就會從follower變成candidate
- 自增當(dāng)前任期,且開始計時(選舉計時)彪杉,向其它節(jié)點發(fā)起投票
- 其它節(jié)點會比較 任期和日志的序號嗤练,至少不能比自己的數(shù)據(jù)舊才會投票給第一個發(fā)起投票的節(jié)點
- 超過半數(shù)節(jié)點投票成功,才會成為leader在讶,否則要等待選舉超時煞抬,再發(fā)起第二輪投票
投票期間重新收到leader心跳
candidate之所以會發(fā)起選舉,是因為沒有收到leader的心跳构哺,但是在選舉期間又重新收到心跳會如何革答?
論文中描述,當(dāng)重新受到leader的心跳時會判斷term曙强,至少不能比自己小残拐,也就是說,即使是因為自己網(wǎng)絡(luò)原因沒有收到心跳而發(fā)起投票碟嘴,也不會終止這次投票溪食,因為老leader的term比現(xiàn)在的要小,自己是自增了一次的娜扇。
但是如果在投票等待期間错沃,已經(jīng)有新的leader產(chǎn)生,并且接收到leader的 appending的RPC時雀瓢,candidate會放棄投票枢析,因為term不小于當(dāng)前candidate,說明這個leader不是老leader刃麸,要么和自己是同一個term的leader醒叁,要么比自己更新term的leader。
所以理論上存在某一個follower的節(jié)點因為網(wǎng)路延遲而發(fā)起leader申請,并且還有可能成功頂替leader的可能性把沼,即使leader的功能正常啊易,是這個follower自己的網(wǎng)絡(luò)突然發(fā)生了延遲。