天天看點

ZooKeeper知識總結

資料模型

ZooKeeper資料模型是一個樹狀的資料結構,類似于檔案系統;和檔案系統的差別在于樹中的每一個節點(葉子節點與非葉子節點)都可以儲存資料,且每個節點的通路都必須從根節點開始,以斜線作為分隔的通路路徑,如 /root/a/b/,它沒有相對路徑的概念,所有的節點都必須通過絕對路徑來通路;

Znode

ZooKeeper樹中的節點被稱之為znode,znode維護了一個stat結構,其中包含了版本号和時間戳;版本号是一直遞增的,每一次znode中包含的資料被更新,版本号也會發生改變;

當用戶端嘗試去更新或者删除一個znode的時候,必須提供它要更新/删除的znode的目前版本号,如果版本号不正确,這個更新/删除就會失敗(有點類似于資料庫操作的樂觀鎖)。

觀察者

用戶端可以給znode添加一個觀察者(類似于事件),當znode發生改變時,這個觀察者會被觸發,相應的用戶端就會收到一個通知;

Zookeeper用戶端可以給三個操作設定觀察者:exists、getChildren、getData:

操作 觸發的時間點
getChildren 當znode的子節點被建立或者删除、當znode自身被删除時觸發
exists 當znode被建立、删除,或者資料被更新時觸發
getData 當znode被删除或znode的資料被更新時觸發

觀察者隻會被觸發一次,如果想被多次觸發,則需要在觸發之後重新注冊;觀察者的常用地方在于,使用ZooKeeper作為一個配置中心,各個用戶端(應用程式)通過觀察者監聽znode進而擷取最新的配置;

順序性Znode

當建立一個Znode時,你可以要求ZooKeeper添加一個單調遞增的計數器到這個znode上,這樣你就可以在同一個父節點下建立多個相同的znode,而每個znode會以一串數字結尾,并單調遞增;

這個計數器隻在同一個父節點下唯一,最大值為2147483647,超過之後則會溢出;

暫時性Znode

Znode包含兩種類型:暫時性znode和持久性znode;當建立這個znode的用戶端session逾時時,暫時性znode會被删除,而持久性的znode與用戶端session無關,隻能被顯式的删除;

暫時性Znode不能有子節點,但它對所有的用戶端是可見的;

順序性Znode和暫時性Znode相結合可以作為分布式鎖,具體操作為:建立順序性znode的最小值的用戶端作為分布式鎖的獲得者,當這個用戶端關閉Session時,其建立的znode會被删除,而剩下的順序性znode最小值的建立者将捕獲這個分布式鎖;為避免驚群效應,每一個用戶端隻需要在比它稍小的那個znode上設定一個觀察者,這樣當znode被删除時,隻會喚醒一個用戶端。

一緻性

選舉

ZooKeeper使用Master/Slave模式,通過ZAB算法實作Leader的選舉機制;

ZooKeeper的所有機器可以分為三類:Leader、Follower、Learner,Learner主要用于同步Znode資料,是以選舉主要在多個Follower之間進行;目的主要在多個Follower中選舉出持有zxid和myid(ZooKeeper伺服器的辨別ID)相對較大(超過過半數的zxid+myid即可)的那個機器作為Leader;

在ZooKeeper叢集中的每一個更新操作都會有一個全局性的唯一性辨別,這個辨別叫做zxid,又稱之為ZooKeeper的事務ID,它永遠是遞增的;

Zxid是一個64位的數字,包含兩部分:任期(epoch)和計數器(counter);其中高32位為任期,低32位為計數器;當一個新的Leader選舉出來之後,任期會加1,在同一個Leader任期内保持計數器(counter)遞增,通過此種方式記錄操作的順序性。

ZAB算法的核心在于多個Follower之間兩兩比較,如果一個Follower的zxid + myid比n/2+1(n為Follower的總數)個Follower都大,則會被選舉出來作為Leader;

正因為選舉需要比較過半數的Follower,如果過半數的Follower當機,則叢集崩潰。

寫操作

ZooKeeper叢集的寫操作都是由Leader來完成的,然後再通過Leader同步到Follower,Zookeeper在傳回結果到用戶端之前并不會保證會同步到所有的Follower,隻需要過半(n/2+1)Follower同步成功即可;

讀操作

用戶端可以連接配接到叢集中任何一台機器進行讀操作,但不能保證都能讀到最新的資料,是以在getData之前最好調用sync操作同步最新的資料再讀取。

我的豆瓣賬号:https://www.douban.com/people/joenzhang