一致性協議 (史上最全)

文章很長,建議收藏起來,慢慢讀! 瘋狂創客圈爲小夥伴奉上如下珍貴的學習資源:html


推薦: 瘋狂創客圈 高質量 博文

高併發 必讀 的精彩博文
nacos 實戰(史上最全) sentinel (史上最全+入門教程)
Zookeeper 分佈式鎖 (圖解+秒懂+史上最全) Webflux(史上最全)
SpringCloud gateway (史上最全) TCP/IP(圖解+秒懂+史上最全)
10分鐘看懂, Java NIO 底層原理 Feign原理 (圖解)
更多精彩博文 ..... 請參見【 瘋狂創客圈 高併發 總目錄

史上最全 Java 面試題 28 專題 總目錄

精心梳理、吐血推薦、史上最強、建議收藏 阿里、京東、美團、頭條.... 隨意挑、橫着走!!!
1.Java算法面試題(史上最強、持續更新、吐血推薦) 2.Java基礎面試題(史上最全、持續更新、吐血推薦)
3.JVM面試題(史上最強、持續更新、吐血推薦) 四、架構設計面試題 (史上最全、持續更新、吐血推薦)
五、Spring面試題 專題 六、SpringMVC面試題 專題
7.SpringBoot - 面試題(史上最強、持續更新) 八、Tomcat面試題 專題部分
9.網絡協議面試題(史上最全、持續更新、吐血推薦) 十、TCP/IP協議(圖解+秒懂+史上最全)
11.JUC併發包與容器 - 面試題(史上最強、持續更新) 十二、設計模式面試題 (史上最全、持續更新、吐血推薦)
13.死鎖面試題(史上最強、持續更新) 15.Zookeeper 分佈式鎖 (圖解+秒懂+史上最全)
1四、Redis 面試題 - 收藏版(史上最強、持續更新) 1六、Zookeeper 面試題(史上最強、持續更新)
1七、分佈式事務面試題 (史上最全、持續更新、吐血推薦) 1八、一致性協議 (史上最全)
1九、Zab協議 (史上最全) 20、Paxos 圖解 (秒懂)
2一、raft 圖解 (秒懂) 2六、消息隊列、RabbitMQ、Kafka、RocketMQ面試題 (史上最全、持續更新)
22.Linux面試題(史上最全、持續更新、吐血推薦) 2三、Mysql 面試題(史上最強、持續更新)
2四、SpringCloud 面試題 - 收藏版(史上最強、持續更新) 2五、Netty 面試題 (史上最強、持續更新)
2七、內存泄漏 內存溢出(史上最全) 2八、JVM 內存溢出 實戰 (史上最全)

常見的一致性協議 有二階段提交(2PC)、三階段提交(3PC)、Paxos、Raft等算法,在本文將介紹他們中的一部分。java

2PC

2PC即Two-Phase Commit,二階段提交。普遍應用在數據庫領域,爲了使得基於分佈式架構的全部節點能夠在進行事務處理時可以保持原子性和一致性。絕大部分關係型數據庫,都是基於2PC完成分佈式的事務處理。
顧名思義,2PC分爲兩個階段處理,程序員

事務提交示意圖
事務中斷示意圖

階段一:提交事務請求

  1. 事務詢問。協調者向全部參與者發送事務內容,詢問是否能夠執行提交操做,並開始等待各參與者進行響應;
  2. 執行事務。各參與者節點,執行事務操做,並將Undo和Redo操做計入本機事務日誌;
  3. 各參與者向協調者反饋事務問詢的響應。成功執行返回Yes,不然返回No。

階段二:執行事務提交

協調者在階段二決定是否最終執行事務提交操做。這一階段包含兩種情形:面試

執行事務提交
全部參與者reply Yes,那麼執行事務提交。算法

  1. 發送提交請求。協調者向全部參與者發送Commit請求;
  2. 事務提交。參與者收到Commit請求後,會正式執行事務提交操做,並在完成提交操做以後,釋放在整個事務執行期間佔用的資源;
  3. 反饋事務提交結果。參與者在完成事務提交後,寫協調者發送Ack消息確認;
  4. 完成事務。協調者在收到全部參與者的Ack後,完成事務。

中斷事務

事情總會出現意外,當存在某一參與者向協調者發送No響應,或者等待超時。協調者只要沒法收到全部參與者的Yes響應,就會中斷事務。sql

  1. 發送回滾請求。協調者向全部參與者發送Rollback請求;
  2. 回滾。參與者收到請求後,利用本機Undo信息,執行Rollback操做。並在回滾結束後釋放該事務所佔用的系統資源;
  3. 反饋回滾結果。參與者在完成回滾操做後,向協調者發送Ack消息;
  4. 中斷事務。協調者收到全部參與者的回滾Ack消息後,完成事務中斷。

2PC具備明顯的優缺點:

優勢主要體如今實現原理簡單;
缺點比較多:數據庫

  • 2PC的提交在執行過程當中,全部參與事務操做的邏輯都處於阻塞狀態,也就是說,各個參與者都在等待其餘參與者響應,沒法進行其餘操做;
  • 協調者是個單點,一旦出現問題,其餘參與者將沒法釋放事務資源,也沒法完成事務操做;
  • 數據不一致。當執行事務提交過程當中,若是協調者向全部參與者發送Commit請求後,發生局部網絡異常或者協調者在還沒有發送完Commit請求,即出現崩潰,最終致使只有部分參與者收到、執行請求。因而整個系統將會出現數據不一致的情形;
  • 保守。2PC沒有完善的容錯機制,當參與者出現故障時,協調者沒法快速得知這一失敗,只能嚴格依賴超時設置來決定是否進一步的執行提交仍是中斷事務。

3PC

針對2PC的缺點,研究者提出了3PC,即Three-Phase Commit。做爲2PC的改進版,3PC將原有的兩階段過程,從新劃分爲CanCommit、PreCommit和do Commit三個階段。
三階段提交示意圖編程

階段一:CanCommit

  1. 事務詢問。協調者向全部參與者發送包含事務內容的canCommit的請求,詢問是否能夠執行事務提交,並等待應答;
  2. 各參與者反饋事務詢問。正常狀況下,若是參與者認爲能夠順利執行事務,則返回Yes,不然返回No。

階段二:PreCommit

在本階段,協調者會根據上一階段的反饋狀況來決定是否能夠執行事務的PreCommit操做。有如下兩種可能:設計模式

執行事務預提交緩存

  1. 發送預提交請求。協調者向全部節點發出PreCommit請求,並進入prepared階段;
  2. 事務預提交。參與者收到PreCommit請求後,會執行事務操做,並將Undo和Redo日誌寫入本機事務日誌;
  3. 各參與者成功執行事務操做,同時將反饋以Ack響應形式發送給協調者,同事等待最終的Commit或Abort指令。

中斷事務
加入任意一個參與者向協調者發送No響應,或者等待超時,協調者在沒有獲得全部參與者響應時,便可以中斷事務:

  1. 發送中斷請求。 協調者向全部參與者發送Abort請求;
  2. 中斷事務。不管是收到協調者的Abort請求,仍是等待協調者請求過程當中出現超時,參與者都會中斷事務;

階段三:doCommit

在這個階段,會真正的進行事務提交,一樣存在兩種可能。

執行提交

  1. 發送提交請求。假如協調者收到了全部參與者的Ack響應,那麼將從預提交轉換到提交狀態,並向全部參與者,發送doCommit請求;
  2. 事務提交。參與者收到doCommit請求後,會正式執行事務提交操做,並在完成提交操做後釋放佔用資源;
  3. 反饋事務提交結果。參與者將在完成事務提交後,向協調者發送Ack消息;
  4. 完成事務。協調者接收到全部參與者的Ack消息後,完成事務。

中斷事務
在該階段,假設正常狀態的協調者接收到任一個參與者發送的No響應,或在超時時間內,仍舊沒收到反饋消息,就會中斷事務:

  1. 發送中斷請求。協調者向全部的參與者發送abort請求;
  2. 事務回滾。參與者收到abort請求後,會利用階段二中的Undo消息執行事務回滾,並在完成回滾後釋放佔用資源;
  3. 反饋事務回滾結果。參與者在完成回滾後向協調者發送Ack消息;
  4. 中端事務。協調者接收到全部參與者反饋的Ack消息後,完成事務中斷。

3PC的優缺點

3PC有效下降了2PC帶來的參與者阻塞範圍,而且可以在出現單點故障後繼續達成一致;
但3PC帶來了新的問題,在參與者收到preCommit消息後,若是網絡出現分區,協調者和參與者沒法進行後續的通訊,這種狀況下,參與者在等待超時後,依舊會執行事務提交,這樣會致使數據的不一致。

Paxos協議

Paxos協議 解決了什麼問題

像 2PC 和 3PC 都須要引入一個協調者的角色,當協調者 down 掉以後,整個事務都沒法提交,參與者的資源都出於鎖定的狀態,對於系統的影響是災難性的,並且出現網絡分區的狀況,頗有可能會出現數據不一致的狀況。有沒有不須要協調者角色,每一個參與者來協調事務呢,在網絡分區的狀況下,又能最大程度保證一致性的解決方案呢。此時 Paxos 出現了。

Paxos 算法是 Lamport 於 1990 年提出的一種基於消息傳遞的一致性算法。因爲算法難以理解起初並無引發人們的重視,Lamport在八年後從新發表,即使如此Paxos算法仍是沒有獲得重視。2006 年 Google 的三篇論文石破天驚,其中的 chubby 鎖服務使用Paxos 做爲 chubbycell 中的一致性,後來才獲得關注。

Paxos 協議是一個解決分佈式系統中,多個節點之間就某個值(提案)達成一致(決議)的通訊協議。它可以處理在少數節點離線的狀況下,剩餘的多數節點仍然可以達成一致。即每一個節點,既是參與者,也是決策者

Paxos 協議的角色(能夠是同一臺機器)

因爲 Paxos 和下文提到的 zookeeper 使用的 ZAB 協議過於類似,詳細講解參照下文, ZAB 協議部分

分佈式系統中的節點通訊存在兩種模型:共享內存(Shared memory)消息傳遞(Messages passing)

基於消息傳遞通訊模型的分佈式系統,不可避免的會發生如下錯誤:進程可能會慢、被殺死或者重啓,消息可能會延遲、丟失、重複,在基礎Paxos場景中,先不考慮可能出現消息篡改,即拜占庭錯誤的狀況。(網絡環境通常爲自建內網,消息安全相對高)

Paxos算法解決的問題是在一個可能發生上述異常的分佈式系統中如何就某個值達成一致,保證不論發生以上任何異常,都不會破壞決議的一致性。

Paxos 協議的角色 主要有三類節點:

  • 提議者(Proposer):提議一個值;
  • 接受者(Acceptor):對每一個提議進行投票;
  • 告知者(Learner):被告知投票的結果,不參與投票過程。
    img

過程:

規定一個提議包含兩個字段:[n, v],其中 n 爲序號(具備惟一性),v 爲提議值。

下圖演示了兩個 Proposer 和三個 Acceptor 的系統中運行該算法的初始過程,每一個 Proposer 都會向全部 Acceptor 發送提議請求。
img

當 Acceptor 接收到一個提議請求,包含的提議爲 [n1, v1],而且以前還未接收過提議請求,那麼發送一個提議響應,設置當前接收到的提議爲 [n1, v1],而且保證之後不會再接受序號小於 n1 的提議。

以下圖,Acceptor X 在收到 [n=2, v=8] 的提議請求時,因爲以前沒有接收過提議,所以就發送一個 [no previous] 的提議響應,而且設置當前接收到的提議爲 [n=2, v=8],而且保證之後不會再接受序號小於 2 的提議。其它的 Acceptor 相似。
img

若是 Acceptor 接受到一個提議請求,包含的提議爲 [n2, v2],而且以前已經接收過提議 [n1, v1]。若是 n1 > n2,那麼就丟棄該提議請求;不然,發送提議響應,該提議響應包含以前已經接收過的提議 [n1, v1],設置當前接收到的提議爲 [n2, v2],而且保證之後不會再接受序號小於 n2 的提議。

以下圖,Acceptor Z 收到 Proposer A 發來的 [n=2, v=8] 的提議請求,因爲以前已經接收過 [n=4, v=5] 的提議,而且 n > 2,所以就拋棄該提議請求;Acceptor X 收到 Proposer B 發來的 [n=4, v=5] 的提議請求,由於以前接收到的提議爲 [n=2, v=8],而且 2 <= 4,所以就發送 [n=2, v=8] 的提議響應,設置當前接收到的提議爲 [n=4, v=5],而且保證之後不會再接受序號小於 4 的提議。Acceptor Y 相似。
img

當一個 Proposer 接收到超過一半 Acceptor 的提議響應時,就能夠發送接受請求。

Proposer A 接受到兩個提議響應以後,就發送 [n=2, v=8] 接受請求。該接受請求會被全部 Acceptor 丟棄,由於此時全部 Acceptor 都保證不接受序號小於 4 的提議。

Proposer B 事後也收到了兩個提議響應,所以也開始發送接受請求。須要注意的是,接受請求的 v 須要取它收到的最大 v 值,也就是 8。所以它發送 [n=4, v=8] 的接受請求。
img

Acceptor 接收到接受請求時,若是序號大於等於該 Acceptor 承諾的最小序號,那麼就發送通知給全部的 Learner。當 Learner 發現有大多數的 Acceptor 接收了某個提議,那麼該提議的提議值就被 Paxos 選擇出來。
img

Raft協議

Paxos 是論證了一致性協議的可行性,可是論證的過程聽說晦澀難懂,缺乏必要的實現細節,並且工程實現難度比較高廣爲人知實現只有 zk 的實現 zab 協議。

Paxos協議的出現爲分佈式強一致性提供了很好的理論基礎,可是Paxos協議理解起來較爲困難,實現比較複雜。

而後斯坦福大學RamCloud項目中提出了易實現,易理解的分佈式一致性複製協議 Raft。Java,C++,Go 等都有其對應的實現

以後出現的Raft相對要簡潔不少。
引入主節點,經過競選。
節點類型:Follower、Candidate 和 Leader

Leader 會週期性的發送心跳包給 Follower。每一個 Follower 都設置了一個隨機的競選超時時間,通常爲 150ms~300ms,若是在這個時間內沒有收到 Leader 的心跳包,就會變成 Candidate,進入競選階段。

基本名詞

  • 節點狀態
    • Leader(主節點):接受 client 更新請求,寫入本地後,而後同步到其餘副本中
    • Follower(從節點):從 Leader 中接受更新請求,而後寫入本地日誌文件。對客戶端提供讀請求
    • Candidate(候選節點):若是 follower 在一段時間內未收到 leader 心跳。則判斷 leader 可能故障,發起選主提議。節點狀態從 Follower 變爲 Candidate 狀態,直到選主結束
  • termId:任期號,時間被劃分紅一個個任期,每次選舉後都會產生一個新的 termId,一個任期內只有一個 leader。termId 至關於 paxos 的 proposalId。
  • RequestVote:請求投票,candidate 在選舉過程當中發起,收到 quorum (多數派)響應後,成爲 leader。
  • AppendEntries:附加日誌,leader 發送日誌和心跳的機制
  • election timeout:選舉超時,若是 follower 在一段時間內沒有收到任何消息(追加日誌或者心跳),就是選舉超時。

競選階段流程

① 下圖表示一個分佈式系統的最初階段,此時只有 Follower,沒有 Leader。Follower A 等待一個隨機的競選超時時間以後,沒收到 Leader 發來的心跳包,所以進入競選階段。
img
② 此時 A 發送投票請求給其它全部節點。
img
③ 其它節點會對請求進行回覆,若是超過一半的節點回復了,那麼該 Candidate 就會變成 Leader。
img
④ 以後 Leader 會週期性地發送心跳包給 Follower,Follower 接收到心跳包,會從新開始計時。
img

多個 Candidate 競選

① 若是有多個 Follower 成爲 Candidate,而且所得到票數相同,那麼就須要從新開始投票,例以下圖中 Candidate B 和 Candidate D 都得到兩票,所以須要從新開始投票。
img
② 當從新開始投票時,因爲每一個節點設置的隨機競選超時時間不一樣,所以能下一次再次出現多個 Candidate 並得到一樣票數的機率很低。
img

日誌複製

① 來自客戶端的修改都會被傳入 Leader。注意該修改還未被提交,只是寫入日誌中。
img
② Leader 會把修改複製到全部 Follower。
img
③ Leader 會等待大多數的 Follower 也進行了修改,而後纔將修改提交。
img
④ 此時 Leader 會通知的全部 Follower 讓它們也提交修改,此時全部節點的值達成一致。
img

ZAB協議

ZAB協議 概述

Google 的粗粒度鎖服務 Chubby 的設計開發者 Burrows 曾經說過:「全部一致性協議本質上要麼是 Paxos 要麼是其變體」。Paxos 雖然解決了分佈式系統中,多個節點就某個值達成一致性的通訊協議。可是仍是引入了其餘的問題。因爲其每一個節點,均可以提議提案,也能夠批准提案。當有三個及以上的 proposer 在發送 prepare 請求後,很難有一個 proposer 收到半數以上的回覆而不斷地執行第一階段的協議,在這種競爭下,會致使選舉速度變慢

因此 zookeeper 在 paxos 的基礎上,提出了 ZAB 協議,本質上是,只有一臺機器能提議提案(Proposer),而這臺機器的名稱稱之爲 Leader 角色。其餘參與者扮演 Acceptor 角色。爲了保證 Leader 的健壯性,引入了 Leader 選舉機制。

ZAB協議還解決了這些問題

  1. 在半數如下節點宕機,依然能對臺提供服務
  2. 客戶端全部的寫請求,交由 Leader 來處理。寫入成功後,須要同步給全部的 follower 和 observer
  3. leader 宕機,或者集羣重啓。須要確保已經再 Leader 提交的事務最終都能被服務器提交,而且確保集羣能快速回復到故障前的狀態

ZAB協議 基本概念

  • 基本名詞
    • 數據節點(dataNode):zk 數據模型中的最小數據單元,數據模型是一棵樹,由斜槓( / )分割的路徑名惟一標識,數據節點能夠存儲數據內容及一系列屬性信息,同時還能夠掛載子節點,構成一個層次化的命名空間。
    • 事務及 zxid:事務是指可以改變 Zookeeper 服務器狀態的操做,通常包括數據節點的建立與刪除、數據節點內容更新和客戶端會話建立與失效等操做。對於每一個事務請求,zk 都會爲其分配一個全局惟一的事務 ID,即 zxid,是一個 64 位的數字,高 32 位表示該事務發生的集羣選舉週期(集羣每發生一次 leader 選舉,值加 1),低 32 位表示該事務在當前選擇週期內的遞增次序(leader 每處理一個事務請求,值加 1,發生一次 leader 選擇,低 32 位要清 0)。
    • 事務日誌:全部事務操做都是須要記錄到日誌文件中的,可經過 dataLogDir 配置文件目錄,文件是以寫入的第一條事務 zxid 爲後綴,方便後續的定位查找。zk 會採起「磁盤空間預分配」的策略,來避免磁盤 Seek 頻率,提高 zk 服務器對事務請求的影響能力。默認設置下,每次事務日誌寫入操做都會實時刷入磁盤,也能夠設置成非實時(寫到內存文件流,定時批量寫入磁盤),但那樣斷電時會帶來丟失數據的風險。
    • 事務快照:數據快照是 zk 數據存儲中另外一個很是核心的運行機制。數據快照用來記錄 zk 服務器上某一時刻的全量內存數據內容,並將其寫入到指定的磁盤文件中,可經過 dataDir 配置文件目錄。可配置參數 snapCount,設置兩次快照之間的事務操做個數,zk 節點記錄完事務日誌時,會統計判斷是否須要作數據快照(距離上次快照,事務操做次數等於snapCount/2~snapCount 中的某個值時,會觸發快照生成操做,隨機值是爲了不全部節點同時生成快照,致使集羣影響緩慢)。
  • 核心角色
    • leader:系統剛啓動時或者 Leader 崩潰後正處於選舉狀態;
    • follower:Follower 節點所處的狀態,Follower 與 Leader 處於數據同步階段;
    • observer:Leader 所處狀態,當前集羣中有一個 Leader 爲主進程。
  • 節點狀態
    • LOOKING:節點正處於選主狀態,不對外提供服務,直至選主結束;
    • FOLLOWING:做爲系統的從節點,接受主節點的更新並寫入本地日誌;
    • LEADING:做爲系統主節點,接受客戶端更新,寫入本地日誌並複製到從節點

ZAB協議 常見的誤區

  • 寫入節點後的數據,立馬就能被讀到,這是錯誤的。** zk 寫入是必須經過 leader 串行的寫入,並且只要一半以上的節點寫入成功便可。而任何節點均可提供讀取服務。例如:zk,有 1~5 個節點,寫入了一個最新的數據,最新數據寫入到節點 1~3,會返回成功。而後讀取請求過來要讀取最新的節點數據,請求可能被分配到節點 4~5 。而此時最新數據尚未同步到節點4~5。會讀取不到最近的數據。若是想要讀取到最新的數據,能夠在讀取前使用 sync 命令**。
  • zk啓動節點不能偶數臺,這也是錯誤的。zk 是須要一半以上節點才能正常工做的。例如建立 4 個節點,半數以上正常節點數是 3。也就是最多隻容許一臺機器 down 掉。而 3 臺節點,半數以上正常節點數是 2,也是最多容許一臺機器 down 掉。4 個節點,多了一臺機器的成本,可是健壯性和 3 個節點的集羣同樣。基於成本的考慮是不推薦的

ZAB協議 選舉同步過程

發起投票的契機

  1. 節點啓動
  2. 節點運行期間沒法與 Leader 保持鏈接,
  3. Leader 失去一半以上節點的鏈接

如何保證事務

ZAB 協議相似於兩階段提交,客戶端有一個寫請求過來,例如設置 /my/test 值爲 1,Leader 會生成對應的事務提議(proposal)(當前 zxid爲 0x5000010 提議的 zxid 爲Ox5000011),現將set /my/test 1(此處爲僞代碼)寫入本地事務日誌,而後set /my/test 1日誌同步到全部的follower。follower收到事務 proposal ,將 proposal 寫入到事務日誌。若是收到半數以上 follower 的迴應,那麼廣播發起 commit 請求。follower 收到 commit 請求後。會將文件中的 zxid ox5000011 應用到內存中。

上面說的是正常的狀況。有兩種狀況。第一種 Leader 寫入本地事務日誌後,沒有發送同步請求,就 down 了。即便選主以後又做爲 follower 啓動。此時這種仍是會日誌會丟掉(緣由是選出的 leader 無此日誌,沒法進行同步)。第二種 Leader 發出同步請求,可是尚未 commit 就 down 了。此時這個日誌不會丟掉,會同步提交到其餘節點中。

服務器啓動過程當中的投票過程

如今 5 臺 zk 機器依次編號 1~5

  1. 節點 1 啓動,發出去的請求沒有響應,此時是 Looking 的狀態
  2. 節點 2 啓動,與節點 1 進行通訊,交換選舉結果。因爲二者沒有歷史數據,即 zxid 沒法比較,此時 id 值較大的節點 2 勝出,可是因爲尚未超過半數的節點,因此 1 和 2 都保持 looking 的狀態
  3. 節點 3 啓動,根據上面的分析,id 值最大的節點 3 勝出,並且超過半數的節點都參與了選舉。節點 3 勝出成爲了 Leader
  4. 節點 4 啓動,和 1~3 個節點通訊,得知最新的 leader 爲節點 3,而此時 zxid 也小於節點 3,因此認可了節點 3 的 leader 的角色
  5. 節點 5 啓動,和節點 4 同樣,選取認可節點 3 的 leader 的角色

服務器運行過程當中選主過程

1.節點 1 發起投票,第一輪投票先投本身,而後進入 Looking 等待的狀態 2.其餘的節點(如節點 2 )收到對方的投票信息。節點 2 在 Looking 狀態,則將本身的投票結果廣播出去(此時走的是上圖中左側的 Looking 分支);若是不在 Looking 狀態,則直接告訴節點 1 當前的 Leader 是誰,就不要瞎折騰選舉了(此時走的是上圖右側的 Leading/following 分支) 3.此時節點 1,收到了節點 2 的選舉結果。若是節點 2 的 zxid 更大,那麼清空投票箱,創建新的投票箱,廣播本身最新的投票結果。在同一次選舉中,若是在收到全部節點的投票結果後,若是投票箱中有一半以上的節點選出了某個節點,那麼證實 leader 已經選出來了,投票也就終止了。不然一直循環

zookeeper 的選舉,優先比較大 zxid,zxid 最大的節點表明擁有最新的數據。若是沒有 zxid,如系統剛剛啓動的時候,則比較機器的編號,優先選擇編號大的

同步的過程

在選出 Leader 以後,zk 就進入狀態同步的過程。其實就是把最新的 zxid 對應的日誌數據,應用到其餘的節點中。此 zxid 包含 follower 中寫入日誌可是未提交的 zxid 。稱之爲服務器提議緩存隊列 committedLog 中的 zxid。

同步會完成三個 zxid 值的初始化。

peerLastZxid:該 learner 服務器最後處理的 zxid。 minCommittedLog:leader服務器提議緩存隊列 committedLog 中的最小 zxid。 maxCommittedLog:leader服務器提議緩存隊列 committedLog 中的最大 zxid。 系統會根據 learner 的peerLastZxid和 leader 的minCommittedLogmaxCommittedLog作出比較後作出不一樣的同步策略

直接差別化同步

場景:peerLastZxid介於minCommittedLogZxidmaxCommittedLogZxid

此種場景出如今,上文提到過的,Leader 發出了同步請求,可是尚未 commit 就 down 了。 leader 會發送 Proposal 數據包,以及 commit 指令數據包。新選出的 leader 繼續完成上一任 leader 未完成的工做。

例如此刻Leader提議的緩存隊列爲 0x20001,0x20002,0x20003,0x20004,此處learn的peerLastZxid爲0x20002,Leader會將0x20003和0x20004兩個提議同步給learner

先回滾在差別化同步/僅回滾同步

此種場景出如今,上文提到過的,Leader寫入本地事務日誌後,還沒發出同步請求,就down了,而後在同步日誌的時候做爲learner出現。

例如即將要 down 掉的 leader 節點 1,已經處理了 0x20001,0x20002,在處理 0x20003 時還沒發出提議就 down 了。後來節點 2 當選爲新 leader,同步數據的時候,節點 1 又神奇復活。若是新 leader 尚未處理新事務,新 leader 的隊列爲,0x20001, 0x20002,那麼僅讓節點 1 回滾到 0x20002 節點處,0x20003 日誌廢棄,稱之爲僅回滾同步。若是新 leader 已經處理 0x30001 , 0x30002 事務,那麼新 leader 此處隊列爲0x20001,0x20002,0x30001,0x30002,那麼讓節點 1 先回滾,到 0x20002 處,再差別化同步0x30001,0x30002。

全量同步

peerLastZxid小於minCommittedLogZxid或者leader上面沒有緩存隊列。leader直接使用SNAP命令進行全量同步

參考文獻:

http://www.javashuo.com/article/p-vjywczat-vh.html

https://blog.csdn.net/weixin_33725272/article/details/87947998

http://ifeve.com/raft/

相關文章
相關標籤/搜索