Apache ZooKeeper是由Apache Hadoop的子項目發展而來,於2010年11月正式成爲了Apache的頂級項目。git
ZooKeeper是一個開放源代碼的分佈式協調服務。它具備高性能、高可用的特色,同時也具備嚴格的順序訪問控制能力(主要是寫操做的嚴格順序性)。基於對ZAB協議(ZooKeeper Atomic Broadcast,ZooKeeper原子消息廣播協議)的實現,它可以很好地保證分佈式環境中數據的一致性。也正是基於這樣的特性,使得ZooKeeper成爲了解決分佈式數據一致性問題的利器。github
ZooKeeper總體架構算法
請見上圖,文字說明以下:數據庫
ZooKeeper由兩部分組成:ZooKeeper服務端和客戶端。apache
ZooKeeper服務器採用集羣的形式。值得一提的是,只要集羣中存在超過一半的、處於正常工做狀態的服務器,那麼整個集羣就可以正常對外服務。組成ZooKeeper集羣的每臺服務器都會在內存中維護當前的ZooKeeeper服務狀態,而且每臺服務器之間都互相保持着通訊。服務器
客戶端在鏈接ZooKeeper服務集羣時,會按照必定的隨機算法選擇集羣中的某臺服務器,而後和它共同建立一個TCP鏈接,使客戶端連上到那臺服務器。而當那臺服務器失效時,客戶端自動會從新選擇另外一臺服務器進行鏈接,從而保證服務的連續性。架構
當其中一個客戶端修改數據時,ZooKeeper會將修改同步到集羣中全部的服務器上,從而使鏈接到集羣中其它服務器上的客戶端也能當即看到修改後的數據,很好地保證了分佈式環境中數據的一致性。負載均衡
ZooKeeper數據模型運維
請見上圖,文字說明以下:分佈式
Zookeeper的數據模型採用相似於文件系統的樹結構。樹上的每一個節點稱爲ZNode,而每一個節點均可能有一個或者多個子節點。ZNode的節點路徑標識方式是由一系列斜槓【/】進行分割的路徑表示。
能夠向ZNode節點寫入、修改、讀取數據,也能夠建立、刪除ZNode節點或ZNode節點下的子節點。值得注意的是,ZooKeeper的設計目標不是傳統的數據庫存儲或者大數據對象存儲,而是協同數據的存儲,所以在實現時ZNode存儲的數據大小不該超過1MB。另外,每個節點都有個ACL(Access Control List,訪問控制列表),據此控制該節點的訪問權限。
ZNode數據節點是有生命週期的,其生命週期的長短取決於數據節點的節點類型。節點類型共有4種:持久節點(PERSISTENT)、持久順序節點(PERSISTENT_SEQUENTIAL)、臨時節點(EPHEMERAL)、臨時順序節點(EPHEMERAL_SEQUENTIAL)。
ZooKeeper的Watcher機制,歸納爲三個過程:客戶端註冊Watcher成爲訂閱者、服務端處理Watcher以及客戶端回調Watcher。
客戶端在本身須要關注的位於ZooKeeper服務器裏的ZNode節點上註冊一個Watcher監聽後,一旦這個ZNode節點發生變化,則在該節點上註冊過Watcher監聽的全部客戶端會收到ZNode節點變化通知。在收到通知時,客戶端經過回調Watcher作相應的處理,從而實現特定的功能。
經過對ZooKeeper中豐富的數據節點類型進行交叉使用,配合Watcher事件通知機制,能夠很是方便地構建分佈式應用中都會涉及的核心功能,如:數據發佈/訂閱(即配置中心)、負載均衡、命名服務、分佈式協調/通知、集羣管理、Master選舉、分佈式鎖和分佈式隊列等。
Demo中的【ConfigServiceDemo(配置服務Demo)】適用於ZooKeeper的配置中心應用場景:
應用中用到的一些經常使用配置信息放到ZooKeeper的一系列ZNode節點上,供應用獲取配置數據;同時,若是某應用在須要關注的配置項節點上註冊了個Watcher,則之後每次被關注的配置項有更新的時候,都會實時通知到該應用,從而達到獲取最新配置信息的目的。
a. 減小咱們的運維工做人員的工做量:當公司的應用程序以集羣環境模式被部署的時候,若第1次部署應用程序或遇到須要配置新增/修改/刪除的狀況,咱們的運維工做人員不得不爲集羣中的每臺服務器進行一臺一臺地修改。而利用了ZooKeeper後,他們只須要修改一次,就能爲集羣中的全部服務器完成配置新增/修改/刪除。
b. 使任意客戶端可以看到即時生效的被改後的配置數據:目前現狀:因爲運維工做人員須要爲集羣中的每臺服務器進行一臺一臺地配置修改,而致使出現了配置延時問題,使得集羣中的每臺服務器的配置數據不一致。也就是說,客戶端(如應用程序)可能會沒法當即讀取到最新的配置值,須要過段時間後才能讀取到。當運維工做人員利用ZooKeeper修改配置數據後,新的配置數據會當即被同步到集羣中的全部服務器,從而保證集羣中的全部服務器的配置數據對於任意客戶端而言每時每刻都是準確無誤的(可選加Watcher)。
下圖顯示的是ZooKeeper配置服務頁面。
咱們都知道,集羣中的服務器通常只有1臺起着Master角色。一旦這臺具備Master角色的服務器出現宕機狀況,則就出現了服務器單點故障問題。而且,咱們並不知道這臺具備Master角色的服務器是從何時開始處於宕機狀態。利用ZooKeeper的「對在ZooKeeper上建立的臨時順序節點(EPHEMERAL_SEQUENTIAL),一旦建立它的客戶端與ZooKeeper服務集羣之間的會話失效,那麼該臨時節點也就被自動清除」這一特性,再加上Watcher事件通知機制的使用,就可以解決服務器的單點故障問題——一旦當前具備Master角色的服務器宕機了,它建立的臨時順序節點(EPHEMERAL_SEQUENTIAL)會立刻消失;緊接着集羣中註冊過Watcher的全部服務器會立刻收到當前Master服務器已宕機的通知,而後將從新進行Master選舉。