新一代分布式數(shù)據(jù)庫采用浪潮云溪數(shù)據(jù)庫Raft共識算法實(shí)現(xiàn)多副本之間數(shù)據(jù)和外部讀取的一致性。在云溪數(shù)據(jù)庫的底層實(shí)現(xiàn)中,通過以下新聞?lì)愋蛯?shí)現(xiàn)Raft機(jī)制的運(yùn)行。其中,本地新聞是指節(jié)點(diǎn)創(chuàng)建新聞后,新聞由自己處理。節(jié)點(diǎn)間的新聞是指節(jié)點(diǎn)在創(chuàng)建新聞后將新聞發(fā)送到其他節(jié)點(diǎn)并由其處理。
- 本地新聞 -
MsgHup
Follower節(jié)點(diǎn)持有選舉計(jì)時(shí)器,當(dāng)節(jié)點(diǎn)持有的選舉計(jì)時(shí)器超過預(yù)設(shè)的選舉時(shí)間閾值時(shí),就會創(chuàng)建MsgHup新聞。具體操作包括:
Follower節(jié)點(diǎn)調(diào)用選舉計(jì)時(shí)器,加1選舉計(jì)數(shù);
檢查當(dāng)前Follower是否存在節(jié)點(diǎn)Raft如果集群不存在,則拒絕創(chuàng)建MsgHup消息。如果存在Raft在集群中,檢查選舉計(jì)數(shù)是否大于或等于設(shè)定的選舉時(shí)間閾值。如果小于設(shè)定的選舉時(shí)間閾值,則拒絕創(chuàng)建MsgHup否則創(chuàng)建新聞MsgHup消息。
在創(chuàng)建出MsgHup消息后,現(xiàn)在Follower將節(jié)點(diǎn)切換成PreCandidate狀態(tài),等待下一步。
MsgCheckQuorum
MsgCheckQuorum新聞的作用是檢測當(dāng)前消息Leader節(jié)點(diǎn)能否與Raft大部分節(jié)點(diǎn)通信集群。Leader當(dāng)心跳計(jì)時(shí)器超時(shí)時(shí),節(jié)點(diǎn)持有心跳計(jì)時(shí)器。Leader節(jié)點(diǎn)將發(fā)送節(jié)點(diǎn)MsgCheckQuorum新聞。具體操作包括:
Leader節(jié)點(diǎn)調(diào)用心跳計(jì)時(shí)器,選舉計(jì)數(shù)加1;
檢查選舉計(jì)數(shù)是否大于或等于設(shè)定的選舉時(shí)間閾值。如果滿足條件,將選舉計(jì)數(shù)設(shè)置為0,然后創(chuàng)建MsgCheckQuorum消息。
由于MsgCheckQuorum新聞屬于本地新聞,所以目前Leader節(jié)點(diǎn)會收到MsgCheckQuorum消息。Leader節(jié)點(diǎn)將根據(jù)自己記錄的其他節(jié)點(diǎn)的活躍信息來判斷Leader節(jié)點(diǎn)是否與其他節(jié)點(diǎn)連接。如果不連接,節(jié)點(diǎn)將從Leader狀態(tài)切換成Follower狀態(tài)。
MsgBeat
MsgBeat通過Leader創(chuàng)建節(jié)點(diǎn)Leader節(jié)點(diǎn)持有的心跳計(jì)時(shí)器超時(shí)后會發(fā)送MsgBeat新聞。具體操作包括:
Leader調(diào)用心跳計(jì)時(shí)器,將心跳計(jì)數(shù)加1;
檢查心跳計(jì)數(shù)是否大于或等于設(shè)定的心跳時(shí)間閾值。如果滿足條件,將心跳計(jì)數(shù)設(shè)置為0,然后創(chuàng)建MsgBeat消息。
由于MsgBeat新聞屬于本地新聞,所以目前Leader節(jié)點(diǎn)會收到MsgBeat消息。然后Leader將節(jié)點(diǎn)發(fā)送到其他節(jié)點(diǎn)MsgHeartbeat心跳消息Follower節(jié)點(diǎn)收到MsgHeartbeat為了防止新聞重置自己的選舉計(jì)時(shí)器Follower新一輪起了新一輪選舉。
MsgTransferLeader和MsgTimeoutNow
將節(jié)點(diǎn)的Leader狀態(tài)轉(zhuǎn)移到其他Follower該過程涉及節(jié)點(diǎn)MsgTransferLeader消息和MsgTimeoutNow消息的處理。Leader狀態(tài)轉(zhuǎn)移,即指定一個(gè)Follower節(jié)點(diǎn)作為下一個(gè)任期的Leader節(jié)點(diǎn),當(dāng)前Leader選擇合適的節(jié)點(diǎn)并發(fā)送節(jié)點(diǎn)MsgTransferLeader消息。
當(dāng)Follower節(jié)點(diǎn)接收到MsgTimeoutNow消息后,將切換成Candidate狀態(tài)并發(fā)起選舉。
- 節(jié)點(diǎn)間消息 -
MsgPreVote
當(dāng)Follower節(jié)點(diǎn)接收到MsgHup本地消息時(shí),自身會切換成PreCandidate然后創(chuàng)建狀態(tài)MsgPreVote消息,并向其他節(jié)點(diǎn)廣播該消息,MsgPreVote攜帶的消息Term節(jié)點(diǎn)本身記錄的值Term值。
收到集群中其他節(jié)點(diǎn)MsgPreVote消息后,對MsgPreVote新聞處理包括:
若攜帶消息Term值大于當(dāng)前節(jié)點(diǎn)記錄的值Term值,檢測此MsgPreVote消息是否為Leader節(jié)點(diǎn)遷移時(shí)發(fā)出的信息及其自身記錄Leader節(jié)點(diǎn)是否存在,以確定當(dāng)前節(jié)點(diǎn)是否參與選舉。如果確定參加選舉,當(dāng)前節(jié)點(diǎn)將決定是否根據(jù)自己的狀態(tài)投票MsgPreVote發(fā)送消息的節(jié)點(diǎn)。
若攜帶消息Term值小于當(dāng)前節(jié)點(diǎn)記錄的值Term值,直接發(fā)送MsgPreVote新聞節(jié)點(diǎn)拒絕投票。
MsgPreVoteResp
處于PreCandidate集群中的其他節(jié)點(diǎn)將返回狀態(tài)節(jié)點(diǎn)MsgPreVoteResp消息,當(dāng)PreCandidate當(dāng)節(jié)點(diǎn)收到超過一半的同意選票時(shí),它將被切換成Candidate狀態(tài),發(fā)起正式選舉。但是,如果你收到拒絕選票,而且MsgPreVoteResp攜帶的消息Term值大于當(dāng)前節(jié)點(diǎn)記錄的值Term當(dāng)前節(jié)點(diǎn)切換為值Follower狀態(tài),同時(shí)自己記錄的狀態(tài)Term值置為MsgPreVoteResp攜帶的消息Term停止下一個(gè)選舉過程。
MsgVote
在處于PreCandidate接到半數(shù)以上同意選票后,狀態(tài)節(jié)點(diǎn)將發(fā)起新一輪選舉,并將其切換成Candidate狀態(tài),然后將其發(fā)送到集群中的其他節(jié)點(diǎn)MsgVote消息。
MsgVoteResp
在處于Candidate接收狀態(tài)節(jié)點(diǎn)MsgVoteResp消息后,對MsgVoteResp新聞處理包括:
若MsgVoteResp攜帶的消息Term值大于當(dāng)前節(jié)點(diǎn)記錄的值Term當(dāng)前節(jié)點(diǎn)切換為值Follower狀態(tài),同時(shí)自己記錄的狀態(tài)Term值置為MsgPreVoteResp攜帶的消息Term停止下一個(gè)選舉過程。
檢查當(dāng)前節(jié)點(diǎn)是否收到超過一半的同意選票。如果是,將當(dāng)前節(jié)點(diǎn)切換成Leader狀態(tài),然后將消息發(fā)送到集群中的其他節(jié)點(diǎn)MsgApp消息。如果沒有,將當(dāng)前節(jié)點(diǎn)切換成Follower狀態(tài)。
MsgApp
MsgApp新聞的作用是Leader將節(jié)點(diǎn)復(fù)制到集群中的其他節(jié)點(diǎn)Entry記錄。在對MsgVote在新聞處理過程中,集群中的其他節(jié)點(diǎn)已被切換Follower狀態(tài),自己記錄的狀態(tài)Term值與當(dāng)前Leader節(jié)點(diǎn)維護(hù)的Term相同的價(jià)值。當(dāng)他們收到它時(shí)Leader節(jié)點(diǎn)發(fā)來的MsgApp消息時(shí),會MsgApp攜帶的消息Entry記錄追加到raftLog最后,創(chuàng)建相應(yīng)的MsgAppResp消息返回給Leader節(jié)點(diǎn)。
在處于Follower接收狀態(tài)節(jié)點(diǎn)MsgApp消息后,對MsgApp新聞處理包括:
重置選舉計(jì)時(shí)器,防止目前Follower節(jié)點(diǎn)選舉;
設(shè)置當(dāng)前節(jié)點(diǎn)記錄Leader信息;
追加Entry記錄;
MsgAppResp
不論Follower節(jié)點(diǎn)追加Entry成功或失敗,都會走向Leader節(jié)點(diǎn)回復(fù)MsgAppResp消息。Leader集群中的其他節(jié)點(diǎn)接收Follower節(jié)點(diǎn)發(fā)送的MsgAppResp響應(yīng)消息后,會根據(jù)自己記錄下來。Follower對于節(jié)點(diǎn)的狀態(tài)信息,選擇不同的添加方法添加節(jié)點(diǎn)Entry記錄,如單個(gè)追加,連續(xù)追加。Leader節(jié)點(diǎn)保存節(jié)點(diǎn)Entery記錄中找不到對應(yīng)Follower需要添加節(jié)點(diǎn)Entry在記錄時(shí),您將選擇發(fā)送快照并添加它Entry。
MsgHeartbeat
在處于Follower接收狀態(tài)節(jié)點(diǎn)MsgHeartbeat消息后,對MsgHeartbeat新聞處理包括:
重置選舉計(jì)時(shí)器,防止目前Follower節(jié)點(diǎn)選舉;
設(shè)置當(dāng)前節(jié)點(diǎn)記錄Leader信息;
試著修改現(xiàn)狀Follower已提交節(jié)點(diǎn)記錄Entry的Index檢查當(dāng)前節(jié)點(diǎn)是否值Leader節(jié)點(diǎn)在Entry記錄中有沖突。如果發(fā)生沖突,自己做。Index信息放到MsgHeartbeatResp等待發(fā)送消息;
發(fā)送MsgHeartbeatResp新聞,響應(yīng)心跳。
MsgHeartbeatResp
在處于Leader接收狀態(tài)節(jié)點(diǎn)MsgHeartbeatResp消息后,對MsgHeartbeatResp新聞處理包括:
更新相應(yīng)節(jié)點(diǎn)的活躍信息表示Follower節(jié)點(diǎn)能否與自己連接;
重置相應(yīng)節(jié)點(diǎn)Entry可以記錄方式Follower連續(xù)追加節(jié)點(diǎn)Entry記錄;
根據(jù)響應(yīng)消息檢測到Follower節(jié)點(diǎn)與Leader的Entry如果記錄有沖突,調(diào)整自己的記錄Follower節(jié)點(diǎn)狀態(tài)信息開始添加到節(jié)點(diǎn)中Entry記錄。
檢查在Leader節(jié)點(diǎn)中沒有這個(gè)Follower節(jié)點(diǎn)追加的Entry將記錄發(fā)送到節(jié)點(diǎn)MsgApp消息完成Entry追加記錄。
MsgProp
客戶端通過MsgProp信息向集群發(fā)送寫作請求,Raft集群中只有Leader節(jié)點(diǎn)可以響應(yīng)客戶端的寫作請求。當(dāng)集群中Candidate接收客戶端發(fā)送的節(jié)點(diǎn)MsgProp這個(gè)消息會被直接忽略。Follower節(jié)點(diǎn)收到MsgProp這將是消息的時(shí)候MsgProp消息轉(zhuǎn)發(fā)給當(dāng)前集群Leader節(jié)點(diǎn)。
在處于Leader接收狀態(tài)節(jié)點(diǎn)MsgProp消息后,對MsgProp新聞處理包括:
檢測MsgProp是否攜帶消息Entry如未攜帶記錄,則輸出異常日志并終止程序;
如果當(dāng)前節(jié)點(diǎn)是用來檢測當(dāng)前節(jié)點(diǎn)是否被移出集群的Leader如果狀態(tài)被移出集群,將不再處理MsgProp消息;
檢測當(dāng)前Raft集群是否在進(jìn)行Leader如果節(jié)點(diǎn)轉(zhuǎn)移,則不再處理MsgProp消息;
如果所有上述策略都通過,則將通過Entry將記錄保存到當(dāng)前節(jié)點(diǎn)并通過MsgApp消息向集群中其他節(jié)點(diǎn)追加Entry記錄。
MsgSnap
在Leader節(jié)點(diǎn)嘗試向集群中的Follower節(jié)點(diǎn)發(fā)送MsgApp如果找不到待發(fā)送的消息,Entry會通過記錄MsgSnap消息將快照數(shù)據(jù)發(fā)送到Follower節(jié)點(diǎn)。Follower節(jié)點(diǎn)可以通過快照數(shù)據(jù)恢復(fù)自己的狀態(tài)Leader節(jié)點(diǎn)正常Entry記錄追加。
在處于Follower接收狀態(tài)節(jié)點(diǎn)MsgSnap消息后,對MsgSnap新聞處理包括:
重置選舉計(jì)時(shí)器,防止目前Follower節(jié)點(diǎn)選舉;
設(shè)置當(dāng)前節(jié)點(diǎn)記錄Leader信息;
Follower節(jié)點(diǎn)根據(jù)快照進(jìn)行恢復(fù),之后向Leader節(jié)點(diǎn)回復(fù)MsgAppResp消息。
- 小結(jié) -
本文主要介紹Raft通過上述介紹的消息類型,共識算法在云溪數(shù)據(jù)庫中定義的消息類型實(shí)現(xiàn)并保證了復(fù)制數(shù)據(jù)的同步。可以看出,云溪數(shù)據(jù)庫Raft算法將共識分解為預(yù)選舉模塊、正式選舉模塊、探索模塊、日志復(fù)制模塊等幾個(gè)關(guān)鍵模塊。在此基礎(chǔ)上,將分布式一致性的復(fù)雜問題分為一系列模塊化問題,大大降低了算法的復(fù)雜性。