Zookeeper是開源的分佈式協調服務,提供了分佈式數據一致性的解決方案。node
Zookeeper 可用做配置中心和分佈式鎖服務,在 Dubbo、Kafka、Spark等分佈式集羣上獲得普遍應用。算法
Zookeeper的數據模型爲樹狀結構,樹的節點被稱做ZNode。安全
Zookeeper使用路徑來惟一標識ZNode,相似於Unix文件系統中的絕對路徑。路徑必須以/
開頭,由Unicode字符串組成,如/myapp/master/0
。網絡
每個ZNode維護着三部分數據:app
每一個節點都有獨立的訪問控制列表(Access Control List, ACL), 來控制用戶對本節點的訪問權限。分佈式
每個ZNode都維護着三個版本號:設計
全部的寫操做都會使相應的版本號增長。寫操做必須指定要更新的ZNode的版本號,版本號不一致會致使寫入失敗。code
Zxidblog
全部對Zookeeper狀態的改變都會產生一個Zxid(ZooKeeper Transaction Id),Zxid全局有序。隊列
Zxid爲標識事件發生的前後順序: 即事件A發生早於事件B,那麼事件A的Zxid定小於事件B的Zxid。
每一個ZNode維護兩個Zxid:
Zxid是一個64位的數字, 高32位表示Zookeeper集羣leader, 低32位表示邏輯順序。每次leader改變後, 新產生的Zxid高32位都會改變。
節點類型
Zookeeper中的節點分爲兩種:
Zookeeper 能夠建立順序子節點,即建立子節點時在路徑結尾添加一個自增的32位 id, 該id在該節點的父節點下是惟一的。
Zookeeper 全部的讀操做getData(), getChildren()和 exists()均可以設置 Watch 觸發器。
Watch 觸發器是一次性的,當觸發器通知了一次狀態變化後消失,不會通知狀態的再次變化。
Zookeeper 與客戶端之間經過 Tcp Socket 進行通訊, Zookeeper 會主動將時間通知客戶端。
Zookeeper 保證客戶端只有首先收到了Watch通知後,纔會感知到它所設置監視的znode發生了變化。
Zookeeper 支持三種類型的watch:
ZooKeeper 是具備較高一致性的分佈式協調服務,它提供如下保證:
Zookeeper 使用數據副本和崩潰恢復機制保證數據安全和集羣高可用性。
Zookeeper 使用基於 Paxos 算法的 ZAB協議(Zookeeper Atomic Broadcast)進行寫操做,保證集羣數據的一致性。
咱們能夠將系統中通用配置信息寫入 ZNode 中,客戶端啓動時從 Zookeeper 獲取配置數據並監視配置節點的變化,當配置發生改變 Zookeeper 會通知全部的客戶端獲取最新數據,從而實如今線更新配置。
適合使用Zookeeper維護的配置一般:
當服務啓動時,服務提供者能夠在Zookeeper的相應路徑下建立臨時節點,並在節點中寫入服務配置信息。服務關閉(崩潰)時,臨時節點自動刪除。
客戶端啓動時從 ZooKeeper 讀取服務提供者信息從而實現自動的服務發佈/移除功能。
Zookeeper 的臨時節點能夠維護客戶端持有鎖的狀態,加鎖失敗的客戶端可使用 Watch 機制監視鎖的釋放狀況,實現阻塞等待加鎖。
Zookeeper 的順序節點能夠實現一個簡單的隊列,能夠利用此特性實現公平鎖。客戶端在鎖節點下建立順序子節點,持有最小子節點的客戶端成功加鎖,加鎖失敗的客戶端 Watch 前一個順序子節點,從而實現先到先得的公平鎖機制。
ZooKeeper 的順序節點能夠生成全局惟一ID, 咱們能夠利用該ID爲服務命名。相對於UUID, 該名稱較短且能夠保證毫不重複。
與分佈式公平鎖應用相似,ZooKeeper 能夠維護集羣 Master。
集羣中全部能夠成爲 Master 的進程都在 Zookeeper 中的指定路徑下建立順序子節點,持有最小子節點的進程成爲Master。
集羣中全部進程都 Watch 指定路徑下節點的狀況,一旦發生變化則從新讀取最小子節點的持有者做爲Master。
腦裂問題
傳統集羣實現方案是運行一個備用Master節點,備用Master節點按期向主Master節點發送ping請求,若能及時收到主Master的ack響應則認爲正常。
若Ack響應超時,備用Master則會取代原主Master成爲新的集羣主Master節點。
若響應超時由於主Master故障致使,備用Master成爲新的主節點徹底正常。
若超時由於主備 Master 節點間 ping-ack 網絡故障致使,那麼主Master工做正常,而備用Master卻誤認爲主Master崩潰而進行取代,那麼集羣中可能出現多個Master共存的故障(即腦裂故障)。
若使用 Zookeeper 維護 Master 信息,不管是由於主Master故障仍是通訊問題致使最小子節點被刪除,備用Master持有的節點都會成爲最小子節點。
此時,全部客戶端都會受到通知並得知 Master 變動,保證集羣中只有一個 Master。
當崩潰的Master恢復後,它將成爲新的備用Master加入集羣。
ZooKeeper 沒法避免通訊故障致使誤判 Master 狀態,可是能夠保證在任何狀況下集羣中只有一個 Master 節點。