日誌複製能夠說是Raft集羣的核心之一,保證了Raft數據的一致性,下面經過幾張圖片介紹Raft集羣中日誌複製的邏輯與流程;併發
在一個Raft集羣中只有Leader節點可以接受客戶端的請求,由Leader向其餘Follower轉發全部請求日誌,而且有那麼兩條規則:Leader不刪除任何日誌、Follower只接收Leader所發送的日誌信息;3d
此圖介紹了Raft集羣中日誌的組成結構,日誌由序號與條目組成,每一個條目又由任期與指令組成,committed範圍內爲已提交的日誌是指過半節點已經接收並存儲的日誌;日誌
上圖從整個上介紹了Raft集羣的日誌複製流程,Leader接收到指令後寫入到本地日誌,在隨後的心跳中(AppendEntries)往其餘追隨者發送該條目,等待收到過半追隨者響應後將該條目標誌位已提交狀態,併發往狀態機執行,完成後返回結果給客戶端;在後續心跳包(AppendEntries)中通知全部追隨者哪些條目爲已提交狀態,以便追隨者更新在本身狀態機中執行該指令; 只有Leader可以接受客戶端的指令,追隨者只可以接收領導者的AppendEntries請求;blog
在Raft集羣中可經過條目索引號、任期號惟一肯定一個條目,該條目前序全部條目也是一致的,如上圖中索引號爲5的條目爲已提交狀態的條目,則從索引號1到5的全部條目均爲已提交的狀態;索引
上圖中Leader發送AppendEntries請求時帶有其前序索引位置四、前序任期號2,發往Follower一、Follower2;
Follower1因爲前序索引與前序任期能匹配本地條目因此將會接受該請求;
Follower2因爲前序索引與前序任期未可以匹配因此拒絕該請求;圖片
Raft處理日誌不一致的狀況是經過強制追隨者複製領導者日誌來調整日誌一致性的,因此當追隨者與領導者出現日誌不一致時,追隨者日誌將會被領導者日誌覆蓋;get
要使領導者與追隨者保持一致性的狀態,須要二者找到一致性的位置,刪除追隨者該位置以後全部日誌條目,發送領導者日誌給追隨者;
領導者經過在每個追隨者維護了一個 nextIndex,表示下一個須要發送給跟隨者的日誌條目索引地址,領導者剛得到選舉時,初始化全部 nextIndex 值爲本身的最後一條日誌的index加1;當追隨者的日誌和領導者不一致,那在下一次的AppendEntries時的一致性檢查會失敗,被追隨者拒絕後,領導者就會減少 nextIndex 值進行重試,nextIndex 會在某位置使領導者和追隨者日誌達成一致。
當日志達成一致時,追隨者會接受該AppendEntries請求,這時追隨者衝突的日誌條目將所有被領導者的日誌所覆蓋。一旦AppendEntries成功,那麼跟隨者的日誌就會和領導人保持一致,而且在接下來的任期裏一直繼續保持。it
參考資料:
http://ramcloud.stanford.edu/raft.pdfclass
文章首發地址:Solinx
http://www.solinx.co/archives/1221pdf