新聞中心
用動圖講解分布式 raft
作者:悟空聊架構(gòu) 2021-01-26 13:27:11
開發(fā)
前端
分布式 Raft 算法是分布式系統(tǒng)開發(fā)選擇的共識算法。比如現(xiàn)在流行 Etcd、Consul。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了崇左免費建站歡迎大家使用!
一、Raft 概述
Raft 算法是分布式系統(tǒng)開發(fā)選擇的共識算法。比如現(xiàn)在流行 Etcd、Consul。
如果掌握了這個算法,就可以較容易地處理絕大部分場景的容錯和一致性需求。比如分布式配置系統(tǒng)、分布式 NoSQL 存儲等等,輕松突破系統(tǒng)的單機(jī)限制。
Raft 算法是通過一切以領(lǐng)導(dǎo)者為準(zhǔn)的方式,實現(xiàn)一系列值的共識和各節(jié)點日志的一致。
二、Raft 角色
2.1 角色
跟隨者(Follower):普通群眾,默默接收和來自領(lǐng)導(dǎo)者的消息,當(dāng)領(lǐng)導(dǎo)者心跳信息超時的時候,就主動站出來,推薦自己當(dāng)候選人。
候選人(Candidate):候選人將向其他節(jié)點請求投票 RPC 消息,通知其他節(jié)點來投票,如果贏得了大多數(shù)投票選票,就晉升當(dāng)領(lǐng)導(dǎo)者。
領(lǐng)導(dǎo)者(Leader):霸道總裁,一切以我為準(zhǔn)。處理寫請求、管理日志復(fù)制和不斷地發(fā)送心跳信息,通知其他節(jié)點“我是領(lǐng)導(dǎo)者,我還活著,你們不要”發(fā)起新的選舉,不用找新領(lǐng)導(dǎo)來替代我。
如下圖所示,分別用三種圖代表跟隨者、候選人和領(lǐng)導(dǎo)者。
角色
三、單節(jié)點系統(tǒng)
3.1 數(shù)據(jù)庫服務(wù)器
現(xiàn)在我們想象一下,有一個單節(jié)點系統(tǒng),這個節(jié)點作為數(shù)據(jù)庫服務(wù)器,且存儲了一個值為 X。
數(shù)據(jù)庫服務(wù)器
3.2 客戶端
左邊綠色的實心圈就是客戶端,右邊的藍(lán)色實心圈就是節(jié)點 a(Node a)。Term 代表任期,后面會講到。
客戶端
3.3 客戶端向服務(wù)器發(fā)送數(shù)據(jù)
客戶端向單節(jié)點服務(wù)器發(fā)送了一條更新操作,設(shè)置數(shù)據(jù)庫中存的值為 8。單機(jī)環(huán)境下(單個服務(wù)器節(jié)點),客戶端從服務(wù)器拿到的值也是 8。一致性非常容易保證。
客戶端向服務(wù)器發(fā)送數(shù)據(jù)
3.4 多節(jié)點如何保證一致性?
但如果有多個服務(wù)器節(jié)點,怎么保證一致性呢?比如有三個節(jié)點:a,b,c。如下圖所示。這三個節(jié)點組成一個數(shù)據(jù)庫集群??蛻舳藢@三個節(jié)點進(jìn)行更新操作,如何保證三個節(jié)點中存的值一致?這個就是分布式一致性問題。Raft 算法就是來解決這個問題的。當(dāng)然還有其他協(xié)議也可以保證,本篇只針對 Raft 算法。
在多節(jié)點集群中,在節(jié)點故障、分區(qū)錯誤等異常情況下,Raft 算法如何保證在同一個時間,集群中只有一個領(lǐng)導(dǎo)者呢?下面就開始講解 Raft 算法選舉領(lǐng)導(dǎo)者的過程。
四、選舉領(lǐng)導(dǎo)過程
4.1 初始狀態(tài)
初始狀態(tài)下,集群中所有節(jié)點都是跟隨者的狀態(tài)。
如下圖所示,有三個節(jié)點(Node) a、b、c,任期(Term)都為 0。
初始狀態(tài)
4.2 成為候選者
Raft 算法實現(xiàn)了隨機(jī)超時時間的特性,每個節(jié)點等待領(lǐng)導(dǎo)者節(jié)點心跳信息的超時時間間隔是隨機(jī)的。比如 A 節(jié)點等待超時的時間間隔 150 ms,B 節(jié)點 200 ms,C 節(jié)點 300 ms。那么 a 先超時,最先因為沒有等到領(lǐng)導(dǎo)者的心跳信息,發(fā)生超時。如下圖所示,三個節(jié)點的超時計時器開始運行。
超時時間
當(dāng) A 節(jié)點的超時時間到了后,A 節(jié)點成為候選者,并增加自己的任期編號,Term 值從 0 更新為 1,并給自己投了一票。
- Node A:Term = 1, Vote Count = 1。
- Node B:Term = 0。
- Node C:Term = 0。
成為候選者
4.3 投票
我們來看下候選者如何成為領(lǐng)導(dǎo)者的。
Leader 選舉
- 第一步:節(jié)點 A 成為候選者后,向其他節(jié)點發(fā)送請求投票 RPC 信息,請它們選舉自己為領(lǐng)導(dǎo)者。
- 第二步:節(jié)點 B 和 節(jié)點 C 接收到節(jié)點 A 發(fā)送的請求投票信息后,在編號為 1 的這屆任期內(nèi),還沒有進(jìn)行過投票,就把選票投給節(jié)點 A,并增加自己的任期編號。
- 第三步:節(jié)點 A 收到 3 次投票,得到了大多數(shù)節(jié)點的投票,從候選者成為本屆任期內(nèi)的新的領(lǐng)導(dǎo)者。
- 第四步:節(jié)點 A 作為領(lǐng)導(dǎo)者,固定的時間間隔給 節(jié)點 B 和節(jié)點 C 發(fā)送心跳信息,告訴節(jié)點 B 和 C,我是領(lǐng)導(dǎo)者,組織其他跟隨者發(fā)起新的選舉。
- 第五步:節(jié)點 B 和節(jié)點 C 發(fā)送響應(yīng)信息給節(jié)點 A,告訴節(jié)點 A 我是正常的。
4.4 任期
英文單詞是 term,領(lǐng)導(dǎo)者是有任期的。
- 自動增加:跟隨者在等待領(lǐng)導(dǎo)者心跳信息超時后,推薦自己為候選人,會增加自己的任期號,如上圖所示,節(jié)點 A 任期為 0,推舉自己為候選人時,任期編號增加為 1。
- 更新為較大值:當(dāng)節(jié)點發(fā)現(xiàn)自己的任期編號比其他節(jié)點小時,會更新到較大的編號值。比如節(jié)點 A 的任期為 1,請求投票,投票消息中包含了節(jié)點 A 的任期編號,且編號為 1,節(jié)點 B 收到消息后,會將自己的任期編號更新為 1。
- 恢復(fù)為跟隨者:如果一個候選人或者領(lǐng)導(dǎo)者,發(fā)現(xiàn)自己的任期編號比其他節(jié)點小,那么它會立即恢復(fù)成跟隨者狀態(tài)。這種場景出現(xiàn)在分區(qū)錯誤恢復(fù)后,任期為 3 的領(lǐng)導(dǎo)者受到任期編號為 4 的心跳消息,那么前者將立即恢復(fù)成跟隨者狀態(tài)。
- 拒絕消息:如果一個節(jié)點接收到較小的任期編號值的請求,那么它會直接拒絕這個請求,比如任期編號為 6 的節(jié)點 A,收到任期編號為 5 的節(jié)點 B 的請求投票 RPC 消息,那么節(jié)點 A 會拒絕這個消息。
4.5 選舉規(guī)則
一個任期內(nèi),領(lǐng)導(dǎo)者一直都會領(lǐng)導(dǎo)者,直到自身出現(xiàn)問題(如宕機(jī)),或者網(wǎng)絡(luò)問題(延遲),其他節(jié)點發(fā)起一輪新的選舉。
在一次選舉中,每一個服務(wù)器節(jié)點最多會對一個任期編號投出一張選票,投完了就沒了。
4.6 大多數(shù)
假設(shè)一個集群由 N 個節(jié)點組成,那么大多數(shù)就是至少 N/2+1。例如:3 個節(jié)點的集群,大多數(shù)就是 2。
4.7 心跳超時為了防止多個節(jié)點同時發(fā)起投票,會給每個節(jié)點分配一個隨機(jī)的選舉超時時間。這個時間內(nèi),節(jié)點不能成為候選者,只能等到超時。比如上述例子,節(jié)點 A 先超時,先成為了候選者。這種巧妙的設(shè)計,在大多數(shù)情況下只有一個服務(wù)器節(jié)點先發(fā)起選舉,而不是同時發(fā)起選舉,減少了因選票瓜分導(dǎo)致選舉失敗的情況。
成為候選者
五、領(lǐng)導(dǎo)者故障
如果領(lǐng)導(dǎo)者節(jié)點出現(xiàn)故障,則會觸發(fā)新的一輪選舉。如下圖所示,領(lǐng)導(dǎo)者節(jié)點 B 發(fā)生故障,節(jié)點 A 和 節(jié)點 B 就會重新選舉 Leader。
領(lǐng)導(dǎo)者故障
- 第一步 :節(jié)點 A 發(fā)生故障,節(jié)點 B 和節(jié)點 C 沒有收到領(lǐng)導(dǎo)者節(jié)點 A 的心跳信息,等待超時。
- 第二步:節(jié)點 C 先發(fā)生超時,節(jié)點 C 成為候選人。
- 第三步:節(jié)點 C 向節(jié)點 A 和節(jié)點 B 發(fā)起請求投票信息。
- 第四步:節(jié)點 C 響應(yīng)投票,將票投給了 C,而節(jié)點 A 因為發(fā)生故障了,無法響應(yīng) C 的投票請求。
- 第五步:節(jié)點 C 收到兩票(大多數(shù)票數(shù)),成為領(lǐng)導(dǎo)者。
- 第六步:節(jié)點 C 向節(jié)點 A 和 B 發(fā)送心跳信息,節(jié)點 A 響應(yīng)心跳信息,節(jié)點 B 不響應(yīng)心跳信息。
總結(jié)
Raft 算法通過以下幾種方式來進(jìn)行領(lǐng)導(dǎo)選舉,保證了一個任期只有一位領(lǐng)導(dǎo),極大減少了選舉失敗的情況。
- 任期
- 領(lǐng)導(dǎo)者心跳信息
- 隨機(jī)選舉超時時間
- 先來先服務(wù)的投票原則
- 大多數(shù)選票原則
本篇通過動圖的方式來講解 Raft 算法如何選舉領(lǐng)導(dǎo)者,更容易理解和消化。
本文轉(zhuǎn)載自微信公眾號「悟空聊架構(gòu)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系悟空聊架構(gòu)公眾號。
名稱欄目:用動圖講解分布式Raft
當(dāng)前鏈接:http://fisionsoft.com.cn/article/ccdccgg.html


咨詢
建站咨詢
