Apache ZooKeeper是由Apache Hadoop的子項目發展而來,於2010年11月正式成為了Apache的頂級項目。
ZooKeeper是一個開放源代碼的分布式協調服務。它具有高性能、高可用的特點,同時也具有嚴格的順序訪問控制能力(主要是寫操作的嚴格順序性)。基於對ZAB協議(ZooKeeper Atomic Broadcast,ZooKeeper原子消息廣播協議)的實現,它能夠很好地保證分布式環境中數據的一致性。也正是基於這樣的特性,使得ZooKeeper成為了解決分布式數據一致性問題的利器。
ZooKeeper整體架構
請見上圖,文字說明如下:
ZooKeeper由兩部分組成:ZooKeeper服務端和客戶端。
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選舉。
- ZooKeeperDemo下載地址:https://github.com/das2017/ZooKeeperDemo
- ZooKeeper(v3.4.10) 官網:http://zookeeper.apache.org/doc/r3.4.10/
- ZooKeeper客戶端下載地址:https://github.com/ewhauser/zookeeper