功能描述
需要培訓、定制、外包?
請聯(lián)系我們!:800018081
慧都專業(yè)技術團隊幫助您提高效率,節(jié)省成本,降低風險!
* 關于本產(chǎn)品的分類與介紹僅供參考,精準產(chǎn)品資料以介紹為準,如需購買請先行測試。
Zookeeper 作為一個分布式的服務框架,主要用來解決分布式集群中應用系統(tǒng)的一致性問題,它能提供基于類似于文件系統(tǒng)的目錄節(jié)點樹方式的數(shù)據(jù)存儲,但是 Zookeeper 并不是用來專門存儲數(shù)據(jù)的,它的作用主要是用來維護和監(jiān)控你存儲的數(shù)據(jù)的狀態(tài)變化。通過監(jiān)控這些數(shù)據(jù)狀態(tài)的變化,從而可以達到基于數(shù)據(jù)的集群管理。
數(shù)據(jù)模型
Zookeeper 會維護一個具有層次關系的數(shù)據(jù)結構,它非常類似于一個標準的文件系統(tǒng):如下圖所示:

Zookeeper 這種數(shù)據(jù)結構有如下這些特點:
每個子目錄項如 NameService 都被稱作為 znode,這個 znode 是被它所在的路徑標識,如 Server1 這個 znode 的標識為 /NameService/Server1
znode 可以有子節(jié)點目錄,并且每個 znode 可以存儲數(shù)據(jù),注意 EPHEMERAL 類型的目錄節(jié)點不能有子節(jié)點目錄
znode 是有版本的,每個 znode 中存儲的數(shù)據(jù)可以有多個版本,也就是一個訪問路徑中可以存儲多份數(shù)據(jù)
znode 可以是臨時節(jié)點,一旦創(chuàng)建這個 znode 的客戶端與服務器失去聯(lián)系,這個 znode 也將自動刪除,Zookeeper 的客戶端和服務器通信采用長連接方式,每個客戶端和服務器通過心跳來保持連接,這個連接狀態(tài)稱為 session,如果 znode 是臨時節(jié)點,這個 session 失效,znode 也就刪除了
znode 的目錄名可以自動編號,如 App1 已經(jīng)存在,再創(chuàng)建的話,將會自動命名為 App2
znode 可以被監(jiān)控,包括這個目錄節(jié)點中存儲的數(shù)據(jù)的修改,子節(jié)點目錄的變化等,一旦變化可以通知設置監(jiān)控的客戶端,這個是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于這個特性實現(xiàn)的,后面在典型的應用場景中會有實例介紹
典型應用場景
Zookeeper 從設計模式角度來看,是一個基于觀察者模式設計的分布式服務管理框架,它負責存儲和管理大家都關心的數(shù)據(jù),然后接受觀察者的注冊,一旦這些數(shù)據(jù)的狀態(tài)發(fā)生變化,Zookeeper 就將負責通知已經(jīng)在 Zookeeper 上注冊的那些觀察者做出相應的反應,從而實現(xiàn)集群中類似 Master/Slave 管理模式,關于 Zookeeper 的詳細架構等內(nèi)部細節(jié)可以閱讀 Zookeeper 的源碼。
統(tǒng)一命名服務(Name Service)
分布式應用中,通常需要有一套完整的命名規(guī)則,既能夠產(chǎn)生的名稱又便于人識別和記住,通常情況下用樹形的名稱結構是一個理想的選擇,樹形的名稱結構是一個有層次的目錄結構,既對人友好又不會重復。說到這里你可能想到了 JNDI,沒錯 Zookeeper 的 Name Service 與 JNDI 能夠完成的功能是差不多的,它們都是將有層次的目錄結構關聯(lián)到一定資源上,但是 Zookeeper 的 Name Service 更加是廣泛意義上的關聯(lián),也許你并不需要將名稱關聯(lián)到特定資源上,你可能只需要一個不會重復名稱,就像數(shù)據(jù)庫中產(chǎn)生一個的數(shù)字主鍵一樣。
Name Service 已經(jīng)是 Zookeeper 內(nèi)置的功能,你只要調(diào)用 Zookeeper 的 API 就能實現(xiàn)。如調(diào)用 create 接口就可以很容易創(chuàng)建一個目錄節(jié)點。
配置管理(Configuration Management)
配置的管理在分布式應用環(huán)境中很常見,例如同一個應用系統(tǒng)需要多臺 PC Server 運行,但是它們運行的應用系統(tǒng)的某些配置項是相同的,如果要修改這些相同的配置項,那么就必須同時修改每臺運行這個應用系統(tǒng)的 PC Server,這樣非常麻煩而且容易出錯。
像這樣的配置信息*可以交給 Zookeeper 來管理,將配置信息保存在 Zookeeper 的某個目錄節(jié)點中,然后將所有需要修改的應用機器監(jiān)控配置信息的狀態(tài),一旦配置信息發(fā)生變化,每臺應用機器就會收到 Zookeeper 的通知,然后從 Zookeeper 獲取新的配置信息應用到系統(tǒng)中。

集群管理(Group Membership)
Zookeeper 能夠很容易的實現(xiàn)集群管理的功能,如有多臺 Server 組成一個服務集群,那么必須要一個“總管”知道當前集群中每臺機器的服務狀態(tài),一旦有機器不能提供服務,集群中其它集群必須知道,從而做出調(diào)整重新分配服務策略。同樣當增加集群的服務能力時,就會增加一臺或多臺 Server,同樣也必須讓“總管”知道。
Zookeeper 不僅能夠幫你維護當前的集群中機器的服務狀態(tài),而且能夠幫你選出一個“總管”,讓這個總管來管理集群,這就是 Zookeeper 的另一個功能 Leader Election。
它們的實現(xiàn)方式都是在 Zookeeper 上創(chuàng)建一個 EPHEMERAL 類型的目錄節(jié)點,然后每個 Server 在它們創(chuàng)建目錄節(jié)點的父目錄節(jié)點上調(diào)用getChildren(String path, boolean watch) 方法并設置 watch 為 true,由于是 EPHEMERAL 目錄節(jié)點,當創(chuàng)建它的 Server ,這個目錄節(jié)點也隨之被刪除,所以 Children 將會變化,這時 getChildren上的 Watch 將會被調(diào)用,所以其它 Server 就知道已經(jīng)有某臺 Server 了。新增 Server 也是同樣的原理。

共享鎖(Locks)
共享鎖在同一個進程中很容易實現(xiàn),但是在跨進程或者在不同 Server 之間就不好實現(xiàn)了。Zookeeper 卻很容易實現(xiàn)這個功能,實現(xiàn)方式也是需要獲得鎖的 Server 創(chuàng)建一個 EPHEMERAL_SEQUENTIAL 目錄節(jié)點,然后調(diào)用 getChildren方法獲取當前的目錄節(jié)點列表中最小的目錄節(jié)點是不是就是自己創(chuàng)建的目錄節(jié)點,如果正是自己創(chuàng)建的,那么它就獲得了這個鎖,如果不是那么它就調(diào)用 exists(String path, boolean watch) 方法并監(jiān)控 Zookeeper 上目錄節(jié)點列表的變化,一直到自己創(chuàng)建的節(jié)點是列表中最小編號的目錄節(jié)點,從而獲得鎖,釋放鎖很簡單,只要刪除前面它自己所創(chuàng)建的目錄節(jié)點就行了。

隊列管理
Zookeeper 可以處理兩種類型的隊列:
當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達,這種是同步隊列。
隊列按照 FIFO 方式進行入隊和出隊操作,例如實現(xiàn)生產(chǎn)者和消費者模型。
同步隊列用 Zookeeper 實現(xiàn)的實現(xiàn)思路如下:
創(chuàng)建一個父目錄 /synchronizing,每個成員都監(jiān)控標志(Set Watch)位目錄 /synchronizing/start 是否存在,然后每個成員都加入這個隊列,加入隊列的方式就是創(chuàng)建 /synchronizing/member_i 的臨時目錄節(jié)點,然后每個成員獲取 / synchronizing 目錄的所有目錄節(jié)點,也就是 member_i。判斷 i 的值是否已經(jīng)是成員的個數(shù),如果小于成員個數(shù)等待 /synchronizing/start 的出現(xiàn),如果已經(jīng)相等就創(chuàng)建 /synchronizing/start。
