ZooKeeper架構設計及其應用要點

問題導讀:

1.ZooKeeper的數據模型是什麼 ?
2.ZooKeeper應用有哪些陷阱 ?
3.每一個節點(ZNode)中存儲的是什麼?
4.一個ZNode維護了一個狀態結構都包含了什麼?
5.ZNode組成結構是什麼?
6.Watches的機制是什麼?
7.ZooKeeper內置了哪4種方式實現ACL?






前言php

ZooKeeper 是一個開源的分佈式服務框架,它是ApacheHadoop 項目的一個子項目,主要用來解決分佈式應用場景中存在的一些問題,如:統一命名服務、狀態同步服務、集羣管理、分佈式應用配置管理等,它支持Standalone 模式和分佈式模式,在分佈式模式下,可以爲分佈式應用提供高性能和可靠地協調服務,並且使用ZooKeeper 能夠大大簡化分佈式協調服務的實現,爲開發分佈式應用極大地下降了成本。



整體架構
ZooKeeper 分佈式協調服務框架的整體架構,如圖所示:
<ignore_js_op> 




ZooKeeper 集羣由一組Server 節點組成,這一組Server 節點中存在一個角色爲Leader 的節點,其餘節點都爲Follower 。當客戶端Client 鏈接到ZooKeeper 集羣,而且執行寫請求時,這些請求會被髮送到Leader 節點上,而後Leader 節點上數據變動會同步到集羣中其餘的Follower 節點。
Leader 節點在接收到數據變動請求後,首先將變動寫入本地磁盤,以做恢復之用。當全部的寫請求持久化到磁盤之後,纔會將變動應用到內存中。
ZooKeeper 使用了一種自定義的原子消息協議,在消息層的這種原子特性,保證了整個協調系統中的節點數據或狀態的一致性。Follower 基於這種消息協議可以保證本地的ZooKeeper 數據與Leader 節點同步,而後基於本地的存儲來獨立地對外提供服務。
當一個Leader 節點發生故障失效時,失敗故障是快速響應的,消息層負責從新選擇一個Leader ,繼續做爲協調服務集羣的中心,處理客戶端寫請求,並將ZooKeeper 協調系統的數據變動同步(廣播)到其餘的Follower 節點。

 

設計要點
ZooKeeper 是基於以下4 個目標來進行權衡和設計的,咱們從設計及其特性的角度來詳細說明:

 

 
簡單
分佈式應用中的各個進程能夠經過ZooKeeper 的命名空間(Namespace )來進行協調,這個命名空間是共享的、具備層次結構的,更重要的是它的結構足夠簡單,像咱們平時接觸到的文件系統的目錄結構同樣容易理解,如圖所示:
<ignore_js_op>



 
ZooKeeper 中每一個命名空間(Namespace )被稱爲ZNode ,你能夠這樣理解,每一個ZNode 包含一個路徑和與之相關的元數據,以及繼承自該節點的孩子列表。與傳統文件系統不一樣的是,ZooKeeper 中的數據保存在內存中,實現了分佈式同步服務的高吞吐和低延遲。
在上圖示例的ZooKeeper 的數據模型中,有以下要點:

 

每一個節點(ZNode )中存儲的是同步相關的數據(這是ZooKeeper 設計的初衷,數據量很小,大概B KB 量級),例如狀態信息、配置內容、位置信息等。
一個ZNode 維護了一個狀態結構,該結構包括:版本號、ACL 變動、時間戳。每次ZNode 數據發生變化,版本號都會遞增,這樣客戶端的讀請求能夠基於版本號來檢索狀態相關數據。
每一個ZNode 都有一個ACL ,用來限制是否能夠訪問該ZNode
在一個命名空間中,對ZNode 上存儲的數據執行讀和寫請求操做都是原子的。
客戶端能夠在一個ZNode 上設置一個監視器(Watch ),若是該ZNode 數據發生變動,ZooKeeper 會通知客戶端,從而觸發監視器中實現的邏輯的執行。
每一個客戶端ZooKeeper 鏈接,便創建了一次會話(Session ),會話過程當中,可能發生CONNECTING CONNECTED CLOSED 三種狀態。
ZooKeeper 支持臨時節點(EphemeralNodes )的概念,它是與ZooKeeper 中的會話(Session )相關的,若是鏈接斷開,則該節點被刪除。
 
冗餘
ZooKeeper 被設計爲複製集羣架構,每一個節點的數據均可以在集羣中複製傳播,使集羣中的每一個節點數據同步一致,從而達到服務的可靠性和可用性。前面說到,ZooKeeper 將數據放在內存中來提升性能,爲了不發生單點故障(SPOF ),支持數據的複製來達到冗餘存儲,這是必不可少的。

 

 
有序
ZooKeeper 使用時間戳來記錄致使狀態變動的事務性操做,也就是說,一組事務經過時間戳來保證有序性。基於這一特性。ZooKeeper 能夠實現更加高級的抽象操做,如同步等。

 

 
快速
ZooKeeper 包括讀寫兩種操做,基於ZooKeeper 的分佈式應用,若是是讀多寫少的應用場景(讀寫比例大約是10:1 ),那麼讀性能更可以體現出高效。



數據模型
ZooKeeper 有一個分層的命名空間,結構相似文件系統的目錄結構,很是簡單而直觀。其中,ZNode 是最重要的概念,前面咱們已經描述過。另外,有ZNode 有關的還包括Watches ACL 、臨時節點、序列節點(Sequence Node )。



ZNode 結構
ZooKeeper 中使用Zxid ZooKeeperTransaction Id )來表示每次節點數據變動,一個Zxid 與一個時間戳對應,因此多個不一樣的變動對應的事務是有序的。下面是ZNode 的組成結構,引用文檔以下所示:

 

czxid – The zxid of the change that causedthis znode to be created.
mzxid – The zxid of the change that lastmodified this znode.
ctime – The time in milliseconds from epochwhen this znode was created.
mtime – The time in milliseconds from epochwhen this znode was last modified.
version – The number of changes to the dataof this znode.
cversion – The number of changes to thechildren of this znode.
aversion – The number of changes to the ACLof this znode.
ephemeralOwner – The session id of theowner of this znode if the znode is an ephemeral node. If it is not anephemeral node, it will be zero.
dataLength – The length of the data fieldof this znode.
numChildren – The number of children ofthis znode.



Watches (監視)
ZooKeeper 中的Watch 是隻能觸發一次。也就是說,若是客戶端在指定的ZNode 設置了Watch ,若是該ZNode 數據發生變動,ZooKeeper 會發送一個變動通知給客戶端,同時觸發設置的Watch 事件。若是ZNode 數據又發生了變動,客戶端在收到第一次通知後沒有從新設置該ZNode Watch ,則ZooKeeper 就不會發送一個變動通知給客戶端。
ZooKeeper 異步通知設置Watch 的客戶端。可是ZooKeeper 可以保證在ZNode 的變動生效以後纔會異步地通知客戶端,而後客戶端纔可以看到ZNode 的數據變動。因爲網絡延遲,多個客戶端可能會在不一樣的時間看到ZNode 數據的變動,可是看到變動的順序是可以保證有序一致的。
ZNode 能夠設置兩類Watch ,一個是DataWatches (該ZNode 的數據變動致使觸發Watch 事件),另外一個是Child Watches (該ZNode 的孩子節點發生變動致使觸發Watch 事件)。調用getData() exists()  方法能夠設置Data Watches ,調用getChildren() 方法能夠設置Child Watches 。調用setData() 方法觸發在該ZNode 的註冊的Data Watches 。調用create() 方法建立一個ZNode ,將觸發該ZNode Data Watches ;調用create() 方法建立ZNode 的孩子節點,則觸發ZNode Child Watches 。調用delete() 方法刪除ZNode ,則同時觸發Data Watches Child Watches ,若是該被刪除的ZNode 還有父節點,則父節點觸發一個Child Watches
另外,若是客戶端與ZooKeeper Server 斷開鏈接,客戶端就沒法觸發Watches ,除非再次與ZooKeeper Server 創建鏈接。



Sequence Nodes (序列節點)
在建立ZNode 的時候,能夠請求ZooKeeper 生成序列,以路徑名爲前綴,計數器緊接在路徑名後面,例如,會生成相似以下形式序列
qn-0000000001, qn-0000000002,qn-0000000003, qn-0000000004, qn-0000000005, qn-0000000006, qn-0000000007
對於ZNode 的父節點來講,序列中的每一個計數器字符串都是惟一的,最大值爲2147483647



ACLs (訪問控制列表)
ACL 能夠控制訪問ZooKeeper 的節點,只能應用於特定的ZNode 上,而不能應用於該ZNode 的全部孩子節點上。它主要有以下五種權限:

 

CREATE  容許建立Child Nodes
READ  容許獲取ZNode 的數據,以及該節點的孩子列表
WRITE  能夠修改ZNode 的數據
DELETE  能夠刪除一個孩子節點
ADMIN  能夠設置權限

 

ZooKeeper 內置了4 種方式實現ACL

 

world  一個單獨的ID ,表示任何人均可以訪問
auth  不使用ID ,只有認證的用戶能夠訪問
digest  使用username:password 生成MD5 哈希值做爲認證ID
ip  使用客戶端主機IP 地址來進行認證

 

ZooKeeper Session
當客戶端鏈接到ZooKeeper 集羣時,創建了會話。會話過程當中的狀態變遷,如圖所示:
<ignore_js_op>



創建鏈接過程當中,會話狀態爲CONNECTING ;當鏈接創建成功後,會話狀態變爲CONNECTED 。會話過程當中,若是正常的話,會話的狀態只能是CONNECTING CONNECTED 兩者之一。若是在會話過程當中鏈接斷開,則變爲CLOSED 狀態。



應用陷阱
並不是任何分佈式應用都適合使用ZooKeeper 來構建協調服務,咱們根據ZooKeeper 提供的文檔,給出哪些狀況下使用會出現問題,又是如何應對這種問題的。 總結以下:

 

 
丟失ZNode 上的變動通知
客戶端鏈接到ZooKeeper Server 之後,會維護一個TCP 鏈接。在CONNECTED 狀態下,客戶端設置了某個ZNode Watch 監聽器,能夠收到來自該節點變動的通知(後續會觸發必定的邏輯執行流程)。可是,若是因爲網絡異常,客戶端斷開了與ZooKeeper Server 的鏈接,在斷開的過程當中,是沒法收到ZooKeeper ZNode 上發送的節點數據變動通知的。
因此,若是使用ZooKeeper Watch ,必需要尋找保持CONNECTED Watch ,才能保證不會丟失該Watch 監控的ZNode 上的數據變動通知。

 

 
無效ZooKeeper 集羣節點列表
ZooKeeper 集羣交互時,通常狀況下客戶端會持有一個ZooKeeper 集羣節點的列表,或者列表的子集,那麼會存在以下兩種狀況:
一種狀況是,若是客戶端持有的列表或者列表子集,其中節點都處於Active 狀態,可以提供協調服務,那麼客戶端訪問ZooKeeper 集羣沒有任何問題。
另外一種狀況,客戶端持有ZooKeeper 集羣節點列表或列表子集,若是列表中的某些節點由於故障退出了集羣,若是客戶端再次鏈接這一類失效的節點,就沒法獲取服務。
因此,咱們在應用中使用ZooKeeper 集羣時,必定要明確這一點,或者跳過無效的節點,或者從新尋找有效的節點繼續業務處理,或者檢查ZooKeeper 集羣,使整個集羣恢復正常。



 
配置致使的性能問題
若是設置Java 堆內存(Heap )不合理,會致使ZooKeeper 內存不足,會在內存與文件系統之間進行數據交換,致使ZooKeeper 的性能極大地降低,從而可能會影響應用程序。
爲了不Swapping 問題的出現,主要考慮設置足夠的Java 堆內存,同時減小被操做系統和Cache 使用的內存,儘可能避免在內存與文件系統之間發生數據交換,或者能夠將交換限制在必定的範圍以內。

 

 
事務日誌存儲設備性能
ZooKeeper 會同步事務到存儲設備,若是存儲設備不是專用的,而是和其餘I/O 密集型應用共享同一磁盤,會致使ZooKeeper 的效率。由於客戶端請求ZNode 數據變動而發生的事務,ZooKeeper 會在響應以前將事務日誌寫入存儲設備,若是存儲設備是專用的,那麼整個服務以致外部應用都會得到極大地性能提高。



ZNode 存儲大量數據致使性能問題
ZooKeeper 的設計初衷是,每一個ZNode 只存放少許的同步數據,若是存儲了大量數據,致使ZooKeeper 每次節點發生變動時須要將事務寫入存儲設備,同時還要在集羣內部複製傳播,這將致使不可避免的延遲和性能問題。
因此,若是須要與大量的數據相關,能夠將大量數據存儲在其餘設備中,而只是在ZooKeeper 存儲一個簡單的映射,如指針、引用等等。

 文章轉自:http://www.aboutyun.com/thread-7731-1-1.htmlhtml

相關文章
相關標籤/搜索