Zookeeper的核心:ZAB原子消息廣播協議


 
        ZooKeeper為高可用的一致性協調框架,自然的ZooKeeper也有着一致性算法的實現,ZooKeeper使用的是ZAB協議作為數據一致性的算法,ZAB(ZooKeeper Atomic Broadcast )全稱為:原子消息廣播協議ZAB可以說是在Paxos算法基礎上進行了擴展改造而來的,ZAB協議設計了支持崩潰恢復,ZooKeeper使用單一主進程Leader用於處理客戶端所有事務請求,采用ZAB協議將服務器數狀態以事務形式廣播到所有Follower上;由於事務間可能存在着依賴關系,ZAB協議保證Leader廣播的變更序列被順序的處理,:一個狀態被處理那么它所依賴的狀態也已經提前被處理;ZAB協議支持的崩潰恢復可以保證在Leader進程崩潰的時候可以重新選出Leader並且保證數據的完整性;
  在ZooKeeper中所有的事務請求都由一個主服務器也就是Leader來處理,其他服務器為Follower,Leader將客戶端的事務請求轉換為事務Proposal,並且將Proposal分發給集群中其他所有的Follower,然后Leader等待Follwer反饋,當有過半數(>=N/2+1)的Follower反饋信息后,Leader將再次向集群內Follower廣播Commit信息,Commit為將之前的Proposal提交;

一、協議狀態

ZAB協議中存在着三種狀態,每個節點都屬於以下三種中的一種:
  1. Looking(發現):系統剛啟動時或者Leader崩潰后正處於選舉狀態
  2. Following(同步):Follower節點所處的狀態,Follower與Leader處於數據同步階段;
  3. Leading(領導):Leader所處狀態,當前集群中有一個Leader為主進程;

  ZooKeeper啟動時所有節點初始狀態為Looking,這時集群會嘗試選舉出一個Leader節點選舉出的Leader節點切換為Leading狀態;當節點發現集群中已經選舉出Leader則該節點會切換到Following狀態,然后和Leader節點保持同步;當Follower節點與Leader失去聯系時Follower節點則會切換到Looking狀態,開始新一輪選舉在ZooKeeper的整個生命周期中每個節點都會在Looking、Following、Leading狀態間不斷轉換;

   

 

 

  選舉出Leader節點后ZAB進入原子廣播階段,這時Leader為和自己同步的每個節點Follower創建一個操作序列,一個時期一個Follower只能和一個Leader保持同步,Leader節點與Follower節點使用心跳檢測來感知對方的存在;當Leader節點在超時時間內收到來自Follower的心跳檢測那Follower節點會一直與該節點保持連接;若超時時間內Leader沒有接收到來自過半Follower節點的心跳檢測或TCP連接斷開,那Leader會結束當前周期的領導,切換到Looking狀態,所有Follower節點也會放棄該Leader節點切換到Looking狀態,然后開始新一輪選舉;

二、算法階段

  ZAB協議定義了選舉(election)、發現(discovery)、同步(sync)、廣播(Broadcast)四個階段;ZAB選舉(election)時當Follower存在ZXID(事務ID)時判斷所有Follower節點的事務日志,只有lastZXID的節點才有資格成為Leader,這種情況下選舉出來的Leader總有最新的事務日志,基於這個原因所以ZooKeeper實現的時候把發現(discovery)與同步(sync)合並為恢復(recovery)階段;
  1. Election:在Looking狀態中選舉出Leader節點,Leader的lastZXID總是最新的;
  2. Discovery:Follower節點向准Leader推送FOllOWERINFO,該信息中包含了上一周期的epoch,接受准Leader的NEWLEADER指令,檢查newEpoch有效性,准Leader要確保Follower的epoch與ZXID小於或等於自身的;
  3. sync:將Follower與Leader的數據進行同步,由Leader發起同步指令,最總保持集群數據的一致性;
  4. Broadcast:Leader廣播Proposal與Commit,Follower接受Proposal與Commit;
  5. Recovery:在Election階段選舉出Leader后本階段主要工作就是進行數據的同步,使Leader具有highestZXID,集群保持數據的一致性;

  1、選舉(Election)
  election階段必須確保選出的Leader具有highestZXID,否則在Recovery階段沒法保證數據的一致性,Recovery階段Leader要求Follower向自己同步數據沒有Follower要求Leader保持數據同步,所有選舉出來的Leader要具有最新的ZXID;
  在選舉的過程中會對每個Follower節點的ZXID進行對比只有highestZXID的Follower才可能當選Leader;
選舉流程:
  1. 每個Follower都向其他節點發送選自身為Leader的Vote投票請求,等待回復;
  2. Follower接受到的Vote如果比自身的大(ZXID更新)時則投票,並更新自身的Vote,否則拒絕投票;
  3. 每個Follower中維護着一個投票記錄表,當某個節點收到過半的投票時,結束投票並把該Follower選為Leader,投票結束;

  ZAB協議中使用ZXID作為事務編號,ZXID為64位數字,低32位為一個遞增的計數器,每一個客戶端的一個事務請求時Leader產生新的事務后該計數器都會加1,高32位為Leader周期epoch編號,當新選舉出一個Leader節點時Leader會取出本地日志中最大事務Proposal的ZXID解析出對應的epoch把該值加1作為新的epoch,將低32位從0開始生成新的ZXID;ZAB使用epoch來區分不同的Leader周期;

  2、恢復(Recovery)
  在election階段選舉出來的Leader已經具有最新的ZXID,所有本階段的主要工作是根據Leader的事務日志對Follower節點數據進行更新;
  Leader:Leader生成新的ZXID與epoch,接收Follower發送過來的FOllOWERINFO(含有當前節點的LastZXID)然后往Follower發送NEWLEADER;Leader根據Follower發送過來的LastZXID根據數據更新策略向Follower發送更新指令;
  同步策略:
  1. SNAP:如果Follower數據太老,Leader將發送快照SNAP指令給Follower同步數據;
  2. DIFF:Leader發送從Follolwer.lastZXID到Leader.lastZXID議案的DIFF指令給Follower同步數據;
  3. TRUNC:當Follower.lastZXID比Leader.lastZXID大時,Leader發送從Leader.lastZXID到Follower.lastZXID的TRUNC指令讓Follower丟棄該段數據;
  Follower:往Leader發送FOLLOERINFO指令,Leader拒絕就轉到Election階段;接收Leader的NEWLEADER指令,如果該指令中epoch比當前Follower的epoch小那么Follower轉到Election階段;Follower還有主要工作是接收SNAP/DIFF/TRUNC指令同步數據與ZXID,同步成功后回復ACKNETLEADER,然后進入下一階段;Follower將所有事務都同步完成后Leader會把該節點添加到可用Follower列表中;
  SNAP與DIFF用於保證集群中Follower節點已經Committed的數據的一致性,TRUNC用於拋棄已經被處理但是沒有Committed的數據;

  3、廣播(Broadcast)
  客戶端提交事務請求時Leader節點為每一個請求生成一個事務Proposal,將其發送給集群中所有的Follower節點,收到過半Follower的反饋后開始對事務進行提交,ZAB協議使用了原子廣播協議;在ZAB協議中只需要得到過半的Follower節點反饋Ack就可以對事務進行提交,這也導致了Leader幾點崩潰后可能會出現數據不一致的情況,ZAB使用了崩潰恢復來處理數字不一致問題;消息廣播使用了TCP協議進行通訊所有保證了接受和發送事務的順序性。廣播消息時Leader節點為每個事務Proposal分配一個全局遞增的ZXID(事務ID),每個事務Proposal都按照ZXID順序來處理;
  Leader節點為每一個Follower節點分配一個隊列按事務ZXID順序放入到隊列中,且根據隊列的規則FIFO來進行事務的發送。Follower節點收到事務Proposal后會將該事務以事務日志方式寫入到本地磁盤中,成功后反饋Ack消息給Leader節點,Leader在接收到過半Follower節點的Ack反饋后就會進行事務的提交,以此同時向所有的Follower節點廣播Commit消息,Follower節點收到Commit后開始對事務進行提交;

 

來自 “ ITPUB博客 ” ,鏈接:http://blog.itpub.net/30316686/viewspace-2106956/,如需轉載,請注明出處,否則將追究法律責任。

轉載於:http://blog.itpub.net/30316686/viewspace-2106956/


免責聲明!

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



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