The Zookeeper data model
Zookeeper有一個樹形的namespace,就像分布式文件系統一樣,唯一區別就是這個namespace包括其子節點可以有關聯的數據。就像文件系統允許有文件或者文件夾一樣。節點的路徑通常用絕對的,帶/分隔的字符串表示。任何字符串都可以被使用除了下面所列舉的內容:
·The null character (\u0000) cannot be part of a path name. (This causes problems with the C binding.)
·The following characters can't be used because they don't display well, or render in confusing ways: \u0001 - \u0019 and \u007F - \u009F.
·The following characters are not allowed: \ud800 -uF8FFF, \uFFF0-uFFFF, \uXFFFE - \uXFFFF (where X is a digit 1 - E), \uF0000 - \uFFFFF.
·The "." character can be used as part of another name, but "." and ".." cannot alone be used to indicate a node along a path, because ZooKeeper doesn't use relative paths. The following would be invalid: "/a/b/./c" or "/a/b/../c".
·The token "zookeeper" is reserved.
Znodes
Zookeeper中所有的node都是指znode,znode維護了一個狀態結構,包括data change,acl change,時間戳,version,version對應的時間戳,幫助zookeeper驗證緩存,協助更新。Znode的data發生change,version增加。當客戶端查找data也會同時接收到data的version。當客戶端更新或者刪除某一version的data時,也必須提供data的version。當data和version不匹配,則此次操作失敗(失敗后的處理可被重寫)
Znodes是主要的編程入口,下面是幾個有價值的內容:
Watches
客戶端可以在znodes上設置watches,改變znode的觸發watch的機制和清楚watch。當一個watch觸發,zookeeper會發送一個消息給客戶端。相關連接為
http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html#ch_zkWatches
Data Access
在每個znode的namespace下,數據被自動的讀和寫。讀操作可以獲取znode所有相關的data bytes,寫操作會替換所有的data。每個node都有一個access contril list(ACL)來制約誰有使用權。
Zookeeper不是被設計成一個通用的數據庫或者很大的對象存儲。推薦用做管理協調性的data。Data的來源可以是in the form of configuration,status information,rendezvous,etc.因為這些東西比較小,以kb計量。Zookeeper的client和server確保znodes的data小於1M,並且data平均應該小於1M。大量數據會在網絡和存儲上消耗時間,從而影響性能。大量數據應該被存在hdfs上,zookeeper上存的是數據的路徑等配置。
Ephemeral Node
Zookeeper也有臨時node的概念,這些znodes只會在session活着的時候存在。因此ephemeral node也不允許有子節點。
Sequence Nodes – Unique Naming
當你create一個node同時你可以要求zookeeper在path后面增加一個單調增加的計數,這個計數是唯一的。計數是10位數大小。超過2147483647會溢出
Time in Zookeeper
Zxid
每個對zookeeper state的change都會有一個印記,zxid(zookeeper transaction id),zxid說明了zookeeper所有版本的change,zxid越小,發生的越早
Version number
每個對node的change都會對node的一個version number增加。
有三個version,分別是version(number of changes to the data of a znode),cversion(number of changes to the children of a znode),aversion(number of changes to the ACL of a znode)
Ticks
當使用多servers的zookeeper,servers用ticks定義關於時間的事件,例如status uploads,session timeout,connection timeout between peers.
Real time
Zookeeper不適用實時時間或者時鍾,而是在stat structure里加時間戳。
Zookeeeper stat structure
Stat structure由以下組成
cxid
造成zxid變化的znode創建
mzxid
在這個znode中最后被修改的zxid
ctime
這個znode被創建的毫秒級時間戳
mtime
這個znode最后被修改的時間
version
這個node的change次數
cversion
這個znode的子節點的change次數
aversion
這個znode的ACL的change次數
ephemeralOwner
如果這個znode是Ephemeral node,則為session id,否則就是0
dataLength
這個znode的data fields的長度
numChildren
這個znode的子節點數量
Zookeeper session
一個zookeeper的client通過用語言綁定create handle建立一個和zookeeper service相連的session。一旦創建,handle開始是connection狀態,客戶端的庫嘗試連接zookeeper servers的其中一個,直到狀態切換成connected。一般的操作只有connection和connected兩個狀態。如何有一格不可被恢復的錯誤發生,比如session到期或者權限校驗失敗,或者application 已經關閉了handle,handle會把狀態卻換成closed。下圖說明了zookeeper的client的狀態轉換。
Zookeeper的client會在設置的servers中任意挑選一個連接,如果連接失敗了,client會嘗試用另一個servers去連接,直到連接建立。
當client從zookeeper service中獲得handle,zookeeper會創建一個zookeeper session,用一個64位數表示,並分配給client。當client連接到不同的zookeeper servers,在連接握手中會帶入session id。在有安全措施的情況下,server會為session id創建一個所有zookeeper server都認可的password。這個password在client建立session的過程中會和session id一起發送給client。當client重新和新的servers建立連接的時候,需要把session id和password一起發送servers。
Zookeeper Watches
所有的讀操作,例如getData(),getChildren(),exits(),都有一個設置watch的選項。Zookeeper的watch的定義是,one-time trigger,當dataq發生change發送給設置watch的client,下面是三個關鍵點:
One-time trigger
當client設置了watch,例如getData(“/znode”,true),之后這個data被change了,那watch會接收到一次事件,如果這個data再次被change,則watch不會再接收到事件,除非client再設置getData(“/znode”,true)
Sent to the client
Change事件會發送給client,但是不一定在修改或者初始化change返回成功代碼之前到達。Watches都是被異步發送給watcher。Zookeeper提供了一個順序保證:client不會知道一個watch的change直到client第一次知道watch事件。保證了不同client看到的東西的順序都是一致性的
The data for which the watch was set
Zookeeper維護了兩種watches,data watches和child watches。getData(),exists()是用來設置data watches,getChildren()是用來設置child watches。
只有一種情況下,watch會丟失:一個還沒存在的znode在disconnected狀態下的創建和刪除。
參考資料:
//官網的介紹
http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html#ch_zkSessions
PS
下方是我個人訂閱號,會一直更新各類技術文章,歡迎關注 :)