一文讀懂Zookeeper數據同步流程

 前言

在Zookeeper集羣中,客戶端會隨機鏈接到Zookeeper集羣中 的一個節點。若是是讀請求,就直接從當前節點中讀取數據,若是是寫請求,那麼請求先會被轉發給leader提交事務。而後leader再廣播事務,只要有超過半數節點寫入成功, 那麼寫請求就會被提交(類2PC事務)。整個過程以下圖所示: watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=算法

整套數據同步機制是經過ZAB協議實現的,下面咱們重點了解一下ZAB協議的實現原理。服務器

ZAB協議簡介

ZAB(Zookeeper Atomic Broadcast) 協議是爲Zookeeper專門設計的一種支持崩潰恢復的原子廣播協議。在 ZooKeeper 中,主要依賴ZAB協議來實現 分佈式數據一致性。ZAB協議包含兩種基本模式,分別是崩潰恢復和消息廣播網絡

當整個集羣在啓動時,或者當leader節點出現網絡中斷、 崩潰等狀況時,ZAB協議就會進入恢復模式並選舉產生新的leader,當leader服務器選舉出來後,而且集羣中有過半的機器和該leader節點完成數據同步後(同步指的是數據同步,用來保證集羣中過半的機器可以和 leader服務器的數據狀態保持一致),ZAB協議就會退出恢復模式。分佈式

當集羣中已經有過半的follower節點完成了和leader狀態同步之後,那麼整個集羣就進入了消息廣播模式。這個時候,在leader節點正常工做時,啓動一臺新的服務器加入到集羣,那這個服務器會直接進入數據恢復模式,和leader節點進行數據同步。同步完成後便可正常對外提供非事務請求的處理。ide

leader節點能夠處理事務請求和非事務請求,follower節點只能處理非事務請求,若是follower節點接收到非事務請求,會把這個請求轉發給leader服務器spa

消息廣播實現原理

消息廣播的過程其實是一個 簡化版本的二階段提交過程,具體過程以下:設計

  1. leader接收到消息請求後,將消息賦予一個全局惟一的64位自增id(zxid)。
  2. leader爲每一個follower準備了一個FIFO隊列(經過TCP協議來實現,以實現了全局有序這一個特色)將帶有 zxid的消息做爲一個提案(proposal)分發給全部的follower
  3. follower接收到proposal,先把proposal寫到磁盤,寫入成功之後再向leader回覆一個ack
  4. leader接收到合法數量(超過半數節點)的ACK後,leader就會向這些follower發送commit命令,同時會在本地執行該消息。
  5. follower收到消息的commit命令之後,會提交該消息。

watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=

關於ZXID

zxid是Zookeeper的事務id,爲了保證事務的順序一致性,zookeeper採用了遞增的事務id號(zxid)來標識事務。全部的提案(proposal)都在被提出的時候加上了zxid日誌

zxid是一個64 位數字,高32位是epoch用來標識leader關係是否改變,每次一個leader被選出來,新leader都會將epoch加1,標識當前leader的統治時期。低32位用於遞增計數。code

epoch能夠理解爲當前集羣所處的年代或者週期,每一個leader就像皇帝,都有本身的年號,因此每次改朝換代,leader變動以後,都會在前一個年代的基礎上加 1。這樣就算舊的leader崩潰恢復以後,也沒有人聽他的了,由於follower只遵從當前年代的leader的命令。blog

崩潰恢復實現原理

前面咱們已經講過了ZAB協議中的消息廣播過程,在正常狀況下,上述方式是沒有任何問題的,可是一旦leader 節點崩潰,或者因爲網絡問題致使leader服務器失去了過半的follower節點的聯繫,那麼Zookeeper集羣就會進入到崩潰恢復模式。崩潰恢復狀態下 zab 協議須要作兩件事,選舉出新的leader數據同步

leader失去與過半follower節點聯繫,多是leader節點和follower節點之間產生了網絡分區,那麼此時的leader再也不是合法的leader了。

前面在講解消息廣播時,知道ZAB協議的消息廣播機制是簡化版本的2PC協議,這種協議只須要集羣中過半的節點 響應提交便可。可是它沒法處理leader服務器崩潰帶來的數據不一致問題。所以在 ZAB 協議中添加了一個崩潰恢復模式來解決這個問題。

ZAB協議中的崩潰恢復須要保證,若是一個事務 Proposal 在一臺機器上被處理成功,那麼這個事務應該在全部機器上都被處理成功,哪怕是出現故障。 爲了達到這 個目的,咱們先來設想一下,在Zookeeper中會有哪些場 景緻使數據不一致性,以及針對這些場景,zab協議中的崩潰恢復應該怎麼處理。

已經被處理的消息不能丟

leader收到合法數量followerACK後,就向各個follower廣播COMMIT命令,同時也會在本地執行COMMIT並向鏈接的客戶端返回「成功」。可是若是在各個follower在收到COMMIT命令前leader就掛了,致使剩下的服務器並無執行都這條消息。 watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=

圖中的C2就是一個典型的例子,在集羣正常運過程的某一個時刻, Server1leader服務器,前後廣播了消 息P一、P二、C一、P3和C2。其中當leader服務器把消息C2(Commit事務proposal2)發出後就當即崩潰退出了,那麼針對這種狀況,ZAB協議就須要確保事務Proposal2最終可以在全部的服務器上都能被提交成功,不然將會出現不一致。

被丟棄的消息不能再次出現

leader接收到消息請求生成proposal後就掛了,其餘follower並無到此proposal,所以通過恢復模式從新選了leader後,這條消息是被跳過的。 此時,以前掛了的leader從新啓動並註冊成了 follower, 他保留了被跳過消息的proposal 狀態,與整個系統的狀態是不一致的,須要將其刪除。

解決方案

ZAB協議須要知足上面兩種狀況,就必需要設計一個leader選舉算法。可以確保已經被leader提交的事務 Proposal可以提交、同時丟棄已經被跳過的事務Proposal

  1. 若是leader選舉算法可以保證新選舉出來的leader服務器擁有集羣中全部機器最高編號(ZXID最大)的事務Proposal,那麼就能夠保證這個新選舉出來的leader必定具備已經提交的提案。由於全部提案被COMMIT以前必須有超過半數的follower返回了ACK,即必須有超過半數節點的服務器的事務日誌上有該提案的 proposal,所以,只要有合法數量的節點正常工做,就必然有一個節點保存了全部被COMMIT消息的proposal 狀態。
  2. 另一個,zxid是64位,高32位是epoch編號,每通過一次leader選舉產生一個新的leader,新的 leader會將epoch號+1,低32位是消息計數器,每接收到一條消息這個值+1,新leader選舉後這個值重置爲 0.這樣設計的好處在於老的leader掛了之後重啓,它不會被選舉爲leader,所以此時它的zxid確定小於當前新的leader。當老的leader做爲follower接入新的leader後,新的leader會讓它將全部的擁有舊的 epoch號的未被COMMITproposal清除。

相關文章
相關標籤/搜索