其實網絡上關於Zookeeper的文章多如牛毛,起初,我也只是想寫個學習筆記,作個記錄。可是既然動筆了,我想就不單是作個筆記,而是但願寫一些對讀者有幫助的內容。node
Zookeeper做爲一個流行的分佈式協調服務,要了解他,咱們首先問本身兩個問題,Why and How?咱們爲何要用Zookeeper?Zookeeper是怎麼工做的?web
首先,咱們爲何要用到Zookeeper?咱們能夠把軟件系統類比爲一個公司,當公司規模小的時候,老闆就能決定全部的事情;數據庫
但當公司規模發展壯大後,老闆一我的管理公司有些吃力,但又不放心把全部權力交給另一我的,這時老闆想了個辦法,成立了一個CEO團隊,團隊採用民主化運做進行集體決策。服務器
ECO團隊的主要任務:網絡
相似的,Zookeeper做爲分佈式協調服務,他主要經過兩個手段對外提供服務,即服務目錄 + 通知。數據結構
Zookeeper的應用場景包括:數據發佈/訂閱、命名服務、配置中心、分佈式鎖、集羣管理、選主與服務發現等等。app
先了解下Zookeeper裏的一些基本概念。分佈式
Zookeeper類文件系統中的每一個節點稱爲znode,znode裏包含了節點的自身信息和業務數據,根據節點屬性,能夠分爲2大類,分別是持久化節點和臨時節點,每類下有分爲普通節點和按順序編號節點,分別描述以下:性能
PERSISTENT:持久化目錄節點學習
PERSISTENT_SEQUENTIAL:持久化順序編號目錄節點
EPHEMERAL:臨時目錄節點
EPHEMERAL_SEQUENTIAL:臨時順序編號目錄節點
客戶端註冊監聽它關心的節點,當節點發生變化(數據改變、刪除、子節點增長/刪除)時,監聽器會被觸發,並將事件信息推送到客戶端。
Zookeeper自己做爲一個分佈式服務,有若干節點組成集羣對外提供服務,集羣節點包括Leader、Follower、Observer 3種角色。
Zookeeper客戶端經過TCP長鏈接鏈接到服務集羣,會話(Session)從第一次鏈接開始就已經創建,以後經過心跳檢測機制來保持有效的會話狀態。客戶端經過這個鏈接發送請求並接收響應,接收到Watch事件的通知。
當因爲網絡故障或者客戶端主動斷開等緣由,致使鏈接斷開,此時只要在會話超時(Session TimeOut)時間以內從新創建鏈接,則以前建立的會話依然有效。
對於每一個事務,Zookeeper都會分配一個全局惟一的事務ID(ZXID)。ZXID由64位組成。其中高32位爲紀元號(Epoch:集羣每選舉一次Leader,紀元號加1);低32爲本紀元內的事務序號(事務序號在每一個紀元會清零)
所謂民主選舉,是指當集羣中超過一半的節點贊成一個事務時,即表示事務執行成功(不包括Observer)。Leader提交一個提案時,只要過半數節點反饋ACK,就職務提案被集羣接受了,Leader不須要等待剩餘節點反饋ACK,直接廣播Commit消息;Leader選舉和數據同步時,亦如此。
Zookeeper收到客戶端的一個寫請求,稱爲提案(Proposal),把一個提案提交到集羣並應用生效的過程,叫事務
下面咱們再來看下,做爲一個CEO團隊,它是如何運做的。做爲一個優秀的管理團隊,他的運做要知足CAP原則,即:
團隊經過如下幾條規則確保CAP:
Zookeeper的工做原理,和以上相似。主要依賴ZAB(ZooKeeper Atomic Broadcast)一種支持崩潰恢復的原子廣播協議來完成。
一致性保證
ZAB協議有兩種工做模式,分別是廣播模式和恢復模式。
廣播模式主要用來實現集羣節點間數據的同步,每一個同步操做定義爲一個事務,使用兩階段提交協議完成事務提交,以客戶端寫數據爲例進行說明事務操做:
根據全局有序的規則,Follower提交事務時,須要經過歷史隊列,確認此提案的ZXID是不是最小的,最小才提交,否則就等待其餘ZXID更小的事務先提交
當整個集羣在啓動時,或者Leader失聯後,ZAB協議就會進入恢復模式,恢復模式的流程以下:
Leader選舉是集羣正常運行的前提,當集羣啓動或Leader失聯後,就會進入Leader選舉流程。
選舉期間,集羣間經過選票(Vote) 進行進行互相選舉,選票主要包含兩個信息:
選舉流程:
數據同步流程,是要以Leader數據爲基礎,讓集羣數據達到一致狀態。
遺留問題
根據ZAB協議,Leader已經Commit的事務,從新選主後,要能在新集羣生效。可是有一種狀況,對於一個提案Px,原Leader向集羣廣播提案並收到了過半Follower的ACK,此時Leader會自身先執行Commit再向集羣廣播Commit,但還將來得及向集羣廣播Commit消息,Leader就掛了。
此後經過選舉,原Follower成爲了新Leader,新Leader中Px確定是未Commit的,系統如何保證Px生效呢?這個還沒看研究源碼,有知道請告知下!!
數據的發佈/訂閱系統,一般也用做配置中心。在分佈式系統中,你可能有成千上萬個服務節點,若是想要對全部服務的某項配置進行更改,因爲數據節點過多,你不可逐臺進行修改,而應該在設計時採用統一的配置中心。以後發佈者只須要將新的配置發送到配置中心,全部服務節點便可自動下載並進行更新,從而實現配置的集中管理和動態更新。
Zookeeper經過Watcher機制能夠實現數據的發佈和訂閱。分佈式系統的全部的服務節點能夠對某個ZNode註冊監聽,以後只須要將新的配置寫入該ZNode,全部服務節點都會收到該事件。
在分佈式系統中,一般須要一個全局惟一的名字,如生成全局惟一的訂單號等,Zookeeper能夠經過順序節點的特性來生成全局惟一ID,從而能夠對分佈式系統提供命名服務。
分佈式系統一個重要的模式就是主從模式(Master/Salves),Zookeeper能夠用於該模式下的Matser選舉。可讓全部服務節點去競爭性地建立同一個ZNode,因爲Zookeeper不能有路徑相同的ZNode,必然只有一個服務節點可以建立成功,這樣該服務節點就能夠成爲Master節點。
能夠經過Zookeeper的臨時節點和Watcher機制來實現分佈式鎖,這裏以排它鎖爲例進行說明:
分佈式系統的全部服務節點能夠競爭性地去建立同一個臨時ZNode,因爲Zookeeper不能有路徑相同的ZNode,必然只有一個服務節點可以建立成功,此時能夠認爲該節點得到了鎖。其餘沒有得到鎖的服務節點經過在該ZNode上註冊監聽,從而當鎖釋放時再去競爭得到鎖。鎖的釋放狀況有如下兩種:
當鎖被釋放後,其餘服務節點則再次去競爭性地進行建立,但每次都只有一個服務節點可以獲取到鎖,這就是排他鎖。
Zookeeper還能解決大多數分佈式系統中的問題:
如能夠經過建立臨時節點來創建心跳檢測機制。若是分佈式系統的某個服務節點宕機了,則其持有的會話會超時,此時該臨時節點會被刪除,相應的監聽事件就會被觸發。
參考材料