Zab協議


一、ZooKeeper概述

  ZooKeeper內部有一個in-memory DB,表示為一個樹形結構。每個樹節點稱為Znode(代碼在DataTree.java和DataNode.java中)。

 

 

  客戶端可以連接到zookeeper集群中的任意一台。

  對於讀請求,直接返回本地znode數據。寫操作則轉換為一個事務,並轉發到集群的Leader處理。Zookeeper提交事務保證寫操作(更新)對於zookeeper集群所有機器都是一致的。

二、Zab協議介紹

  Zookeeper使用了一種稱為Zab(Zookeeper Atomic Broadcast)的協議作為其一致性復制的核心,據其作者說這是一種新發算法,其特點是充分考慮了Yahoo的具體情況:高吞吐量、低延遲、健壯、簡單,但不過分要求其擴展性。
  (1)Zookeeper的實現是由Client、Server構成
     Server端提供了一個一致性復制、存儲服務;
    Client端會提供一些具體的語義,比如分布式鎖、選舉算法、分布式互斥等;
  (2)從存儲內容來說,Server端更多的是存儲一些數據的狀態,而非數據內容本身,因此Zookeeper可以作為一個小文件系統使用。數據狀態的存儲量相對不大,完全可以全部加載到內存中,從而極大地消除了通信延遲
  (3)Server可以Crash后重啟,考慮到容錯性,Server必須“記住”之前的數據狀態,因此數據需要持久化,但吞吐量很高時,磁盤的IO便成為系統瓶頸,其解決辦法是使用緩存,把隨機寫變為連續寫。☆☆☆
  (4)安全屬性
  考慮到Zookeeper主要操作數據的狀態,為了保證狀態的一致性,Zookeeper提出了兩個安全屬性(Safety Property)
     全序(Total order):如果消息a在消息b之前發送,則所有Server應該看到相同的結果
     因果順序(Causal order):如果消息a在消息b之前發生(a導致了b),並被一起發送,則a始終在b之前被執行。☆☆
  (5)安全保證
  為了保證上述兩個安全屬性,Zookeeper使用了TCP協議Leader
     通過使用TCP協議保證了消息的全序特性(先發先到)
     通過Leader解決了因果順序問題:先到Leader的先執行。
  因為有了Leader,Zookeeper的架構就變為:Master-Slave模式,但在該模式中Master(Leader)會Crash,因此,Zookeeper引入了Leader選舉算法,以保證系統的健壯性。
  (6)Zookeeper整個工作分兩個階段
     Atomic Broadcast
     Leader選舉
  (7)Zab特性

  ZooKeeper中提交事務的協議並不是Paxos,而是由二階段提交協議改編的ZAB協議。Zab可以滿足以下特性:

    ①可靠提交 Reliable delivery:如果消息m被一個server遞交了,那么m也將最終被所有server遞交。
    ②全局有序 Total order:如果server在遞交b之前遞交了a,那么所有遞交了a、b的server也會在遞交b之前遞交a。
    ③因果有序 Casual order:對於兩個遞交了的消息a、b,如果a因果關系優先於(causally precedes)b,那么a將在b之前遞交。 

  第三條的因果優先指的是同一個發送者發送的兩個消息a先於b發送,或者上一個leader發送的消息a先於當前leader發送的消息。

2.1 Zab工作模式

Zab協議中Server有兩個模式:broadcast模式、recovery模式

(1)恢復模式

  Leader在開始broadcast之前,必須有一個同步更新過的follower的quorum。
  Server在Leader服務期間恢復在線時,將進入recovery模式,與Leader進行同步。

(2)廣播模式

  Broadcast模式使用二階段提交,但是簡化了協議,不需要abort。follower要么ack,要么拋棄Leader,因為zookeeper保證了每次只有一個Leader。另外也不需要等待所有Server的ACK,只需要一個quorum應答就可以了。

 

Follower收到proposal后,寫到磁盤(盡可能批處理),返回ACK。

Leader收到大多數ACK后,廣播COMMIT消息,自己也deliver該消息。

Follower收到COMMIT之后,deliver該消息。

(4)面臨問題

然而,這個簡化的二階段提交不能處理Leader失效的情況,所以增加了recovery模式。切換Leader時,需要解決下面兩個問題。
  ① Never forget delivered messages
      Leader在COMMIT投遞到任何一台follower之前宕機,只有它自己commit了。新Leader必須保證這個事務也必須commit。
    ② Let go of messages that are skipped
      Leader產生某個proposal,但是在宕機之前,沒有follower看到這個proposal。該server恢復時,必須丟棄這個proposal。
(5) 解決方案
  ① 新Leader在propose新消息之前,必須保證事務日志中的所有消息都proposed並且committed。為了保證follower看到所有proposal,以及遞交的消息,Leader向follower發送follower沒有見過的PROPOSAL,以及最后提交的消息的編號之前的COMMIT。
    因為Proposal是保存在follower的事務日志中,並且順序有保證,因此COMMIT的順序也是確定的。解決的第一個問題。
     上個沒有把proposal發送出去的Leader重啟后,新Leader將告訴它截斷事務日志,一直截斷到follower的epoch對應的最后一個commit位置。

三、 Zab與Paxos

3.1 Paxos瓶頸

  ZooKeeper的主要功能是維護一個高可用一致的數據庫,數據庫內容復制在多個節點上,總共2f+1個節點中只要不超過f個失效,系統就可用。實現這一點的核心是ZAB,一種Atomic Broadcast協議。所謂Atomic Broadcast協議,形象的說就是能夠保證發給各復本的消息順序相同
  由於Paxos的名氣太大,所以我看ZAB的時候首先就想為什么要搞個 ZAB,ZAB相比Paxos有什么優點?這里首要一點是Paxos的一致性不能達到ZooKeeper的要求。舉個例子。

  假設一開始Paxos系統中的 leader是P1,他發起了兩個事務<t1, v1>(表示序號為t1的事務要寫的值是v1)和<t2, v2>的過程中掛了。新來個leader是P2,他發起了事務<t1, v1'>。而后又來個新leader是P3,他匯總了一下,得出最終的執行序列<t1, v1'>和<t2, v2>,即P2的t1在前,P1的t2在后。

注意:在這我們可以看出,對於序號為t1的事務,Leader2將Leader1的覆蓋了 

  這樣的序列為什么不能滿足ZooKeeper的需求呢?ZooKeeper是一個樹形結構,很多操作都要先檢查才能確定能不能執行,比如P1的事務t1可能是創建節點“/a”,t2可能是創建節點“/a/aa”,只有先創建了父節點“/a”,才能創建子節點“/a/aa”。而P2所發起的事務t1可能變成了創建“/b”。這樣P3匯總后的序列是先創建“/b”再創建“/a/aa”,由於“/a”還 沒建,創建“a/aa”就搞不定了。

3.2 解決局方案

  為了保證這一點,ZAB要保證同一個leader的發起的事務要按順序被apply,同時還要保證只有先前的leader的所有事務都被apply之后,新選的leader才能在發起事務。

  ZAB 的核心思想,形象的說就是保證任意時刻只有一個節點是leader,所有更新事務由leader發起去更新所有復本(稱為follower),更新時用的就是兩階段提交協議,只要多數節點prepare成功,就通知他們commit。各follower要按當初leader讓他們prepare的順序來 apply事務。因為ZAB處理的事務永遠不會回滾,ZAB的2PC做了點優化,多個事務只要通知zxid最大的那個commit,之前的各 follower會統統commit。☆☆☆
  如果沒有節點失效,那ZAB上面這樣搞下就完了,麻煩在於leader失效或leader得不到多數節點的支持時怎么處理。這里有幾個關鍵點:
   leader所follower之間通過心跳來檢測異常;
   檢測到異常之后的節點若試圖成為新的leader,首先要獲得大多數節點的支持,然后從狀態最新的節點同步事務,完成后才可正式成為leader發起事務;
  ③區分新老leader的關鍵是一個會一直增長的epoch;當然細節很多了,這里就不說了因為我也沒完全搞懂,要了解詳情請看《Zab: High-performance broadcast for primary-backup systems.》這篇論文。
  除了能保證順序外,ZAB的性能也能不錯,基於千兆網絡的測試,一般的5節點部署的TPS達到25000左右,而響應時間只有約6ms。

3.3 Zab與Paoxs 

  Zab的作者認為Zab與paxos並不相同,只所以沒有采用Paxos是因為Paxos保證不了全序順序:
  Because multiple leaders can propose a value for a given instance two problems arise.
  First, proposals can conflict. Paxos uses ballots to detect and resolve conflicting proposals. 
  Second, it is not enough to know that a given instance number has been committed, processes must also be able to figure out which value has been committed.
  Paxos算法的確是 不關心請求之間邏輯順序,而 只考慮數據之間 的全序,但很少有人直接使用paxos算法,都會經過一定的簡化、優化。
一般Paxos都會有幾種簡化形式,其中之一便是,在存在Leader的情況下,可以簡化為1個階段(Phase2)。僅有一個階段的場景需要有一個健壯的Leader,因此工作重點就變為Leader選舉,在考慮到Learner的過程,還需要一個”學習“的階段,通過這種方式,Paxos可簡化為兩個階段:
  • 之前的Phase2
  • Learn
  如果再考慮多數派要Learn成功,這其實就是Zab協議。Paxos算法着重是強調了選舉過程的控制,對決議學習考慮的不多,Zab恰好對此進行了補充。
  之前有人說,所有分布式算法都是Paxos的簡化形式,雖然不是絕對,但對很多情況的確如此,但不知Zab的作者是否認同這種說法?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM