? ? ratis是raft協(xié)議java版本的開源實(shí)現(xiàn)項(xiàng)目糙捺,位于Apache項(xiàng)目下硕淑。項(xiàng)目git地址:https://github.com/apache/ratis。raft協(xié)議是基于日志的強(qiáng)領(lǐng)導(dǎo)模型的共識算法收叶。leader選舉勒葱、集群數(shù)據(jù)同步都離不離開日志。ratis最終目的是為了實(shí)現(xiàn)分布式系統(tǒng)的高可用性惰拱,對于具體的應(yīng)用程序雌贱,ratis使用狀態(tài)機(jī)(StateMachineUpdater)對具體的應(yīng)用程序抽象隔離,保證ratis實(shí)現(xiàn)raft協(xié)議的純粹性和可移植性偿短。
1欣孤、Ratis結(jié)構(gòu)梳理
1、raft協(xié)議
2昔逗、mutli-raft協(xié)議
2降传、ratis正常工作模型
客戶端向raftServerImpl提交請求,請求最終由 RaftLog勾怒、LogAppender婆排、LeaderState、StateMachineUpdater笔链、StateMachine共同完成段只。具體步驟如下:
? ? 1、客戶端向RaftServerImpl發(fā)送請求
? ? ?2卡乾、RaftServerImpl將請求發(fā)送給RaftLog翼悴,構(gòu)建日志并寫入日志文件。
? ? 3、RaftServerImpl將請求提交給LeaderState(返回一個CompelableFuture)鹦赎,等待請求處理完成谍椅。
? ? 4、LogAppender檢測到新增日志古话,復(fù)制日志到對應(yīng)的Follower節(jié)點(diǎn)雏吭,并等待節(jié)點(diǎn)的響應(yīng)。
? ? 5陪踩、LogAppender接收到Follower節(jié)點(diǎn)日志提交成功響應(yīng)后杖们,將日志發(fā)送給LeaderState提交。
? ? 6肩狂、LeaderState檢測到大所屬節(jié)點(diǎn)都已經(jīng)同步成功后摘完,提交日志,并通知StateMachineUpdater服務(wù)
? ? 7傻谁、StateMachineUpdater服務(wù)檢測到新提交的日志孝治,讀取日志并發(fā)送給StateMachine(應(yīng)用程序通過該步驟接收到客戶請求)并處理日志。
? ? 8审磁、StateMachine處理完成提交的日志谈飒,將對應(yīng)日志在LeaderState中的CompletableFuture狀態(tài)更新為完成。
? ? 9态蒂、RaftServerImpl通過CompletableFuture接收到處理結(jié)果杭措,并返回給客戶端。
3钾恢、ratis啟動
? ? ratis啟動可以分解成三個部分:1手素、初始化;2赘那、leader選舉刑桑;3、啟動leader募舟;
1、初始化
? ? 初始化部分是指Ratis正常工作的必要模塊的初始化和啟動闻察。其中就包括:1拱礁、RaftServerImpl的初始化;2辕漂、LifeCycle生命周期管理器初始化呢灶;3、StateMachineUpdater應(yīng)用日志服務(wù)器的初始化和啟動钉嘹,以及作為初始角色Follower對應(yīng)的服務(wù)FollowerState的初始化和啟動鸯乃。其中RaftServerImpl、LifeCycle跋涣、StateMachineUpdater不論節(jié)點(diǎn)屬于什么角色缨睡,這三個服務(wù)都是必要服務(wù)鸟悴。
啟動順序?yàn)椋?/p>
? ? 1、有代理服務(wù)初始化LifeCycle生命周期控制器
? ? 2奖年、構(gòu)建RaftServerImpl服務(wù)實(shí)例细诸,調(diào)用start方法啟動該服務(wù)(這里的star并不是啟動一個單獨(dú)線程)
? ? 3、由RaftServerImpl初始節(jié)點(diǎn)角色管理服務(wù)陋守,并將Follower作為初始角色啟動(設(shè)置角色為:follower震贵,啟動角色對應(yīng)的后臺服務(wù)FoloowerState)。
? ? 4水评、設(shè)置集群為運(yùn)行狀態(tài)(更新LifeCycle的狀態(tài))? ??
2猩系、leader選舉
? ? ratis的leader選舉是由Follower后臺服務(wù)FollowerState觸發(fā),在指定的超時時間范圍內(nèi)沒有接收到Leader心跳請求中燥,就觸發(fā)節(jié)點(diǎn)角色的變更(由Follower角色變更為 Candidate角色蝙眶,并啟動Candidate角色對應(yīng)的后臺服務(wù)LeaderElection),開啟Raft 候選人的leader選舉流程褪那。
如1.2圖:
? ? 第10步:指Follower角色對應(yīng)的后臺服務(wù)FollowerState在指定時間內(nèi)沒有接收到Leader的心跳信息幽纷,于是觸發(fā)角色變更。
? ? 第11步:FollowerState -> RaftServerImpl#changeToCandidate指FollowerState通過Raft頂層服務(wù)RaftServerImpl變更節(jié)點(diǎn)角色博敬,并結(jié)束當(dāng)前服務(wù)(結(jié)束FollowerState服務(wù))
? ? 第12步:RaftServerImpl -> RoleInfo#startLeaderElection指RaftServerImpl通知RoleInfo將節(jié)點(diǎn)角色變更為:Candidate
????第13步:并啟動leader選舉(也就是Candidate角色對應(yīng)的后臺服務(wù) - LeaderElection服務(wù))
? ? ? ?LeaderElection服務(wù)啟動后友浸,就開始向配置文件中配置的其它節(jié)點(diǎn)發(fā)送投票請求。正常清情況下投票請求分為兩個階段:
? ? ? ? ? ? 1偏窝、預(yù)選階段 - Phase.PRE_VOTE
? ? ? ? ? ? ? ? 預(yù)選階段抓喲是檢查當(dāng)前集群是否存在合法的leader收恢,該步驟可以通過配置:raft.server.leaderelection.pre-vote?關(guān)閉該步驟。??
? ? ? ? ? ? 2祭往、競選階段 - Phase.ELECTION
? ? ? ? ? ? ? ? 競選階段就是正式leader競選伦意,candidate向各節(jié)點(diǎn)開始拉票,并在指定節(jié)時間內(nèi)統(tǒng)計得到的投票情況硼补。
3、leader啟動
leader的啟動由LeaderElection選舉通過觸發(fā)。如圖1.2時序圖所示:
? ? 第14步:由LeaderElection調(diào)用RaftServerImpl#changeToLeader,開啟leader上位。
? ? 第15步:RaftServerImpl調(diào)用RoleInfo#shutDownElection碘橘,關(guān)閉LeaderElection后臺服務(wù)屁奏。
? ? 第17步:RaftServerImpl調(diào)用RoleInfo#becomeLeader,將節(jié)點(diǎn)的角色設(shè)置為:leader折联,并初始化啟動LeaderStateImpl祥款。
? ? 第18步:LeaderState初始化并啟動LogAppender抠艾,開啟leader日志同步后臺服務(wù)蛙酪。
至此凹蜂,Ratis服務(wù)leader上位就結(jié)束,可以開啟正常的服務(wù)請求處理了菱父。