raft 5.3 Log replication

Raft 筆記

5.3 Log replication

要保證:

  1. 如果不同日志中兩個(gè)entry有同樣的index和term, 那么儲(chǔ)存的是同一個(gè)指令

    Leader 一次只創(chuàng)建一entry

  2. 如果兩個(gè)不同日志中兩個(gè)entry有同樣的index和term, 那么兩個(gè)entries之前的記錄都是一樣的

    通過(guò)Leader發(fā)送AppendEntries給各個(gè)follower來(lái)檢查是否和Leader的log一致,如果不一致,F(xiàn)ollower就拒絕(拒絕后操作:Leader處理不一致)

    理想情況,Leader和Follower的狀態(tài)是一樣的,但是可能遇到上一個(gè)Leader沒有復(fù)制所有的entries到日志中,或者Leader崩潰,沒來(lái)得及commit log

Leader處理不一致:

當(dāng)Follower和Leader的日志不一致時(shí),Leader強(qiáng)制抹除Follower的日志內(nèi)容并將自己的日志內(nèi)容復(fù)制給Follower(Leader's log == Fowllower's log).

  • 缺失entries,例如(a) (b)

  • 多余的uncommitted entries,例如(c) (d)

  • 兩者都有,例如(e) (f)

Leader發(fā)送AppendEntries 給 Follower 來(lái)找到最新的已經(jīng)committed了的entry,然后少了entries的添上,多了的entries刪除.

對(duì)于每個(gè)Follower,Leader會(huì)維護(hù)一個(gè) nextIndex :index of next log entry the leader will send to that follower

當(dāng)Leader第一次啟動(dòng)(包括更換leader),所有的nextIndex設(shè)置為L(zhǎng)eader log 的下一個(gè)index. 上面圖中是 11

Screen Shot 2021-02-07 at 3.44.44 PM.png

如果Follower's log和leader不一致,那么下一個(gè)AppendEntry就會(huì)失敗。Follower返回rejection,nextIndex--

上圖b和leader的情況:

1.nextIndex是11,sendAppendEntries到b, 發(fā)現(xiàn)index 11沒有指令,nextIndex減一并返回false,一直減到5然后發(fā)現(xiàn)index=4 term = 4匹配Leader的index=4,term=4, 返回true, matchIndex is 4,nextIndex是5。

2.Leader此時(shí)知道4是對(duì)的,將5的指令發(fā)送給b, b index = 5 填上4.

5.4 Safety

前面的一些機(jī)制并不能完全保證每個(gè)狀態(tài)機(jī)執(zhí)行的是相同的指令。比如,當(dāng)Leader提交的時(shí)候,其中一個(gè)follower可能不能用了,就會(huì)commit失敗,然后它被選成了新的Leader,這時(shí)候之前應(yīng)該提交的entries可能被新的entries取代。結(jié)果就是,不同的狀態(tài)機(jī)執(zhí)行了不同的command sequence.

5.4.1 Election restriction

Raft在選取新的Leader的時(shí)候會(huì)檢查candidate是不是擁有所有的committed entries,如果沒有就阻止它成為L(zhǎng)eader: 通過(guò)RequestVote RPC實(shí)現(xiàn): RPC擁有candidate的log信息。

當(dāng)Follower投票時(shí), 它會(huì)拒絕投票如果它的log比candidate的更新(擁有的committed entries更多)

5.4.2 Committing entries from previous terms

不能簡(jiǎn)單的通過(guò)count大多數(shù)entries的方式提交之前term的entry。例如:在(c)中,index2 中的2是大多數(shù),但是(c)不能因?yàn)檫@個(gè)就commit 2. 可能出現(xiàn)(d)和 (e)兩種情況

(d)中,S5成為L(zhǎng)eader后,由于自己的值3擁有比2更大的term,導(dǎo)致用值3將已經(jīng)commit的2覆蓋,所以之前2是不能commit的

下圖描述了當(dāng)一個(gè)old entry儲(chǔ)存在大部分servers上 依然存在被未來(lái)新的Leader重寫的可能。

Screen Shot 2021-01-31 at 6.43.58 PM.png

解決上述問(wèn)題:

因此Raft限制只能通過(guò)判斷大多數(shù)的方式提交當(dāng)前term的entry,進(jìn)而對(duì)之前的entry間接提交,如過(guò)程e所示

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容