🌏【架構師指南】分佈式事務(XA)與一致性算法(Paxos、Raft、Zab、NWR)

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"每日一句","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"生活,一半是回憶,一半是繼續。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"CAP原理","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"要想數據高可用,就得寫多份數據","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"寫多分數據就會導致數據一致性問題","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"數據一致性問題會引起性能問題","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"一致性模型","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"強一致(同步冗餘)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"弱一致性(異步冗餘技術體系)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"最終一致性(一段時間達到一致性)","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"擴展服務的方案","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"數據分區: uid % 16(更多類比分佈式)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"數據鏡像:讓多有的服務器都有相同的數據,提供相當的服務(冗餘存儲,一般3份爲好)(更多類比集羣)","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"兩種方案的事務問題","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"A向B匯錢,兩個用戶不在一個服務器上","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"鏡像:在不同的服務器上對同一數據的寫操作如何保證一致性。","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ee/eec51d060b85776c3de39363a3575300.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"解決一致性事務問題的技術","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Master-Slave","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"讀寫請求由Master負責","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"寫請求寫到Master後,由Master同步到Slave上(由 Master push or Slave pull,通常是由Slave週期性來pull,所以是最終一致性)","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"問題","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":" 若在 pull 週期內(不是期間?),master掛掉,那麼會導致這個時間片內的數據丟失。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":" 若不想讓數據丟掉,Slave只能成爲ReadOnly方式等Master恢復。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":" 若容忍數據丟失,可以讓Slave代替Master工作。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"如何保證強一致性?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Master寫操作,寫完成功後,再寫Slave,兩者成功後返回成功。若Slave失敗,兩種方法標記Slave不可用報錯。","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"Master並繼續服務,Slave等恢復後,再同步Master的數據,多個Slave少了一個而已","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"user"}},{"type":"strong","attrs":{}}],"text":",或者重新嘗試同步slave數據","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"Master回滾自己並返回失敗,帶用戶重新請求,此種方法,數據一致性高可用性高,性能下降很多。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Master-Master","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"數據同步一般是通過Master間的異步完成,所以是最終一致。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 好處: ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"一臺Master掛掉,另外一臺照樣可以提供讀寫服務","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"。","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"當數據沒有被賦值到別的Master上時,數據會丟失","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 對同一數據的處理問題:","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}},{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Dynamo的Vector Clock的設計(記錄數據的版本號和修改者)","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}},{"type":"size","attrs":{"size":10}}],"text":",","attrs":{}},{"type":"text","marks":[{"type":"underline","attrs":{}},{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"當數據發生衝突時,要開發者自己來處理。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"兩階段提交 Two Phase Commit _2PC","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"第一階段:針對準備工作","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"協調者問所有節點是否可以執行提交","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"參與者開始事務,執行準備工作:鎖定資源(獲取鎖操作)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"參與者響應協調者,如果事務的準備工作成功,則迴應\"可以提交\",否則,拒絕提交","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"若消息的傳遞未接收到,則需要協調者作超時處理,要麼當做失敗,要麼重載。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"第二階段:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"若都響應可以提交,則協調者項多有參與者發送正式提交的命令(更新值),參與者完成正式提交,釋放資源,迴應完成。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"協調者收到所有節點的完成響應後結束這個全局事務.。若參與者迴應拒絕提交,則協調者向所有的參與者發送回滾操作,並釋放資源,當收到全部節點的回滾回應後,取消全局事務存在的問題:若一個沒提交,就會進行回滾","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":" 若參與者的迴應超時,要麼重試,要麼把那個參與者即爲問題節點,題出整個集羣,在第二階段中,參與者未收到協調者的指示(也許協調者掛掉),則所有參與者會進入“不知所措” 的狀態(但是已經鎖定了資源),所以引入了三段提交。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"三段提交:把二段提交的第一階段 break 成了兩段","attrs":{}}]},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"詢問","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"鎖定資源(獲取鎖)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"提交","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"核心理念:在詢問的時候並不鎖定資源,除非所有人都同意了,纔開始鎖定。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"好處:當發生了失敗或超時時,三段提交可以繼續把狀態變爲Commit狀態,而二段提交則不知所措?","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Paxos 算法(少數服從多數)","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"解決的問題:一個可能發生異常的分佈式系統中如何就某個值達成一致,讓整個集羣的節點對某個值的變更達成一致","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 任何一個節點都可以提出要修改","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"某個","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"數據的提案,是否通過這個提案取決於這個集羣中是否有超過","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"半數(多數)","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"的節點同意(所以節點數總是單數)—— 版本標記。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 當一個Server接收到比當前版本號小的提案時,則拒絕。當收到比當前大的版本號的提案時,則鎖定資源,進行修改,返回OK。","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"也就是說收到超過一半的最大版本的提案纔算成功。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"核心思想","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"在搶佔式訪問權的基礎上引入多個acceptor,也就是說當一個版本號更大的提案可以剝奪版本號已經獲取的鎖。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"後者認同前者的原則:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":" 肯定舊epoch無法生成確定性取值時,新的epoch會提交自己的value,一旦舊epoch形成確定性取值,新的epoch肯定可以獲取到此取值,並且會認同此取值,不會被破壞。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"步驟","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" P1請求Acceptor的 #1,Acceptor這時並沒有其他線程獲取到鎖,所以把鎖交給P1,並返回這時#1的值爲null","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/a2/a22538d10a6e27ed9a3fe97e18fb62e6.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"然後 P1 向 第一個 Acceptor 提交 #1 的值,Acceptor 接受並返回 OK","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/45/4586cef5e779d6fe9bde908572cede40.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 這個時候,P2向Acceptor請求#1上的鎖,因爲版本號更大,所以直接搶佔了 P1 的鎖。這時 Acceptor 返回了 OK並且返回了 #1 的值","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c0/c0a278f178fb378c096c896831501080.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"這時 P1 向 後面兩個 Acceptor 提交 #1 的值,但是由於中間的那個Acceptor 版本號已經更改爲 2 了,所以拒絕P1。第三個 Acceptor 接受了,並且返回了 OK","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7a/7a01dd574e7bfa9869234cb7d70e068a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"由於後者認同前者的原則,這時P1已經形成確定性取值了 V1 了,這時新的 P2會認同此取值,而不是提交自己的取值。所以,P2會選擇最新的那個取值也就是V1進行提交。這時Acceptor返回 OK","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/41/41b8b4bcb5f107aad7597b3565089fae.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"ZAB算法","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"ZAB 協議 ( Zookeeper Atomic Broadcast) 原子廣播協議:保證了發給各副本的消息順序相同","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":" 定義","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":":原子廣播協議ZAB是一致性協議,Zookeeper把其作爲數據一致性的算法。","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"ZAB是在Paxos算法基礎上進行擴展而來的。Zookeeper使用單一主進程Leader用於處理客戶端所有事務請求,採用ZAB協議將服務器狀態以事務形式廣播到所有Follower上,由於事務間可能存在着依賴關係,ZAB協議保證Leader廣播的變更序列被順序的處理,一個狀態被處理那麼它所依賴的狀態也已經提前被處理。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":" 核心思想:","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"保證任意時刻只有一個節點是Leader,所有更新事務由Leader發起去更新所有副本Follower,更新時用的是兩段提交協議,只要多數節點 prepare 成功,就通知他們commit。","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"各個follower要按當初 leader 讓他們 prepare 的順序來apply事務。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"協議狀態","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"Looking:","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"系統剛啓動時或者Leader崩潰後正處於選舉狀態","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"Following:","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower節點所處的狀態,Follower與 Leader處於數據同步狀態","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"Leading:","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader 所處狀態,當前集羣中有一個 Leader 爲主進程","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"ZooKeeper啓動時所有節點初始狀態爲Looking,這時集羣會嘗試選舉出一個Leader節點,選舉出的Leader節點切換爲Leading狀態;","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"當節點發現集羣中已經選舉出","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"則該節點會切換到","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Following","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"狀態,然後和","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"節點保持同步;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"當","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"節點與","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"失去聯繫時","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"節點則會切換到","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Looking","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"狀態,開始新一輪選舉;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"在","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"ZooKeeper","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"的整個生命週期中每個節點都會在Looking、Following、Leading狀態間不斷轉換。","attrs":{}}]}]}],"attrs":{}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/43/439db30867fb09e1ffc83291f5a1663e.png","alt":null,"title":"","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"border"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"選舉出Leader節點後ZAB進入原子廣播階段,這時Leader爲和自己同步每個節點 Follower 創建一個操作序列,一個時期一個 Follower 只能和一個Leader保持同步","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"階段","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Election","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":":在","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Looking","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"狀態中選舉出","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"節點,","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"LastZXID","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"總是最新的(只有LastZXID的節點纔有資格成爲","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":",這種情況下選舉出來的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"總有最新的事務日誌)。在選舉的過程中會對每個","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"節點的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"ZXID","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"進行對比只有","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"highestZXID","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"纔可能當選","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"每個","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"都向其他節點發送選自身爲Leader的Vote投票請求,等待回覆;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"接受到的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Vote","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"如果比自身的大(","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"ZXID","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"更新)時則投票,並更新自身的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Vote","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":",否則拒絕投票;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":2,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"每個","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"中維護着一個投票記錄表,當某個節點收到過半的投票時,結束投票並把該","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"選爲","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":",投票結束;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Discovery","attrs":{}},{"type":"text","text":":","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"Follower節點向準Leader推送FollwerInfo,該信息包含了上一週期的epoch,接受準 Leader 的 NEWLEADER 指令","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"Sync:將 Follower 與 Leader的數據進行同步,由Leader發起同步指令,最終保持數據的一致性","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"Broadcast:Leader廣播 Proposal 與 Commit,Follower 接受 Proposal 與 commit。因爲一個時刻只有一個Leader節點,若是更新請求,只能由Leader節點執行(","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"若連到的是 Follower 節點,則需轉發到Leader節點執行;讀請求可以從Follower上讀取,若是要最新的數據,則還是需要在Leader上讀取","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":")","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"消息廣播使用了TCP協議進行通訊所有保證了接受和發送事務的順序性。","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"廣播消息時Leader節點爲每個事務Proposal分配一個全局遞增的ZXID(事務ID),每個事務Proposal都按照ZXID順序來處理(Paxos 保證不了)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"Leader節點爲每一個Follower節點分配一個隊列按事務ZXID順序放入到隊列中,且根據隊列的規則FIFO來進行事務的發送。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Recovery :根據Leader的事務日誌對Follower節點數據進行同步更新。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":5},"content":[{"type":"text","text":"同步策略:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"SNAP","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" :如果Follower數據太老,Leader將發送快照SNAP指令給Follower同步數據;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"DIFF","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" :Leader發送從Follower.lastZXID到Leader.lastZXID議案的DIFF指令給Follower同步數據;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"TRUNC","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" :當Follower.lastZXID比Leader.lastZXID大時,Leader發送從Leader.lastZXID到Follower.lastZXID的 TRUNC指令讓Follower丟棄該段數據;(當老Leader在Commit前掛掉,但是已提交到本地)Follower將所有事務都","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"同步完成後,Leader會把該節點添加到可用Follower列表中;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"Follower接收Leader的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"NEWLEADER","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"指令,","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"如果該指令中epoch比當前Follower的epoch小,那麼Follower轉到Election階段","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Raft算法","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"Raft 算法也是一種少數服從多數的算法,在任何時候一個服務器可以扮演以下角色之一:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader:負責Client交互和log複製,同一時刻系統中最多存在一個。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Follower:被動響應請求 RPC,從不主動發起請求 RPC。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Candidate : 由Follower向Leader轉換的中間狀態。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 在選舉Leader的過程中,是有時間限制的,raft 將時間分爲一個個 Term,可以認爲是“邏輯時間”:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 每個Term中至多存在1個 Leader","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 某些Term由於不止一個得到的票數一樣,就會選舉失敗,不存在Leader。則會出現 Split Vote ,再由候選者發出邀票每個 Server 本地維護 currentTerm","attrs":{}}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/85/852fe22743ff1fbde4bb56bcb8920e3c.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"選舉過程:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 自增","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"CurrentTerm","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":",","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"由Follower轉換爲Candidate","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":",設置","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"votedFor","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"爲自身,並行發起","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"RequestVote RPC","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":",不斷重試,直至滿足下列條件之一爲止:","attrs":{}}]},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"獲得超過半數的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Server","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"的投票,轉換爲","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":",廣播","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"HeatBeat","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"接收到合法Leader的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"AppendEnties RPC","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":",轉換爲Follower","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"選舉超時,沒有Server選舉成功,自增currentTerm,重新選舉","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" 當Candidate 在等待投票結果的過程中,可能會接收到來自其他Leader的 AppendEntries RPC ,","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"如果該 Leader 的 Term 不小於本地的 Current Term,則認可該Leader身份的合法性,主動降級爲Follower,反之,則維持 candida 身份繼續等待投票結果","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" Candidate 既沒有選舉成功,也沒有收到其他Leader的 RPC (","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"多個節點同時發起選舉,最終每個 Candidate都將超時","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"),爲了減少衝突,採取隨機退讓策略,每個Candidate重啓選舉定時器。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"日誌更新問題:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"如果在日誌複製過程中,發生了網絡分區或者網絡通信故障,使得Leader不能訪問大多數Followers了,那麼Leader只能正常更新它能訪問的那些Follower服務器,而大多數的服務器Follower因爲沒有了Leader,他們重新選舉一個候選者作爲Leader,然後這個Leader作爲代表於外界打交道,如果外界要求其添加新的日誌,這個新的Leader就按上述步驟通知大多數Followers,如果這時網絡故障修復了,那麼原先的Leader就變成Follower,在失聯階段這個老Leader的任何更新都不能算commit,都回滾,接受新的Leader的新的更新。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"流程","attrs":{}}]},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Client 發送command 命令給 Leader","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader追加日誌項,等待 commit 更新本地狀態機,最終響應 Client","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"若 Client超時,則不斷重試,直到收到響應爲止(重發 command,可能被執行多次,在被執行但是由於網絡通信問題未收到響應)- 冪等性","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"解決辦法:Client 賦予每個 Command唯一標識,Leader在接收 command 之前首先檢查本地log","attrs":{}}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"paxos算法與raft算法的差異","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" Raft 強調是唯一","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"的協議,此","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"至高無上。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" Raft:新選舉出來的","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"Leader","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"擁有全部提交的日誌,","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"而Paxos需要額外的流程從其他節點獲取已經被提交的日誌,它允許日誌有空洞","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":"相同點:得到大多數的贊成,這個entries就會定下來,最終所有節點都會贊成。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"NWR模型","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"N:N個備份","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"W:要寫入至少 w 份才認爲成功","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"color","attrs":{"color":"#40A9FF","name":"blue"}},{"type":"strong","attrs":{}}],"text":"R : 至少讀取R個備份","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}}],"text":" ","attrs":{}},{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"W+ R > N ——> R > N - W (未更新成功的) ,代表每次讀取,都至少讀取到一個最新的版本(更新成功的),從而不會讀到一份舊數據","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":"問題:並非強一致性,會出現一些節點上的數據並不是最新版本,但卻進行了最新的操作。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"size","attrs":{"size":10}},{"type":"strong","attrs":{}}],"text":" 版本衝突問題:矢量鍾Vector Clock : 誰更新的我,我的版本號是什麼(對於同一個操作者的同一操作,版本號遞增)","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章