一、 Zookeeper的資料結構
對于ZooKeeper而言,其存儲結構類似于檔案系統,也是一個樹形目錄服務,并通過Key-Value鍵值對的形式進行資料存儲。其中,Key由斜線間隔的路徑元素構成。對于Zookeeper而言,其名稱空間中的各節點皆用唯一路徑來辨別,其操作和維護的資料節點稱為znode。若需在節點中存儲資料,則以位元組數組的形式進行存儲。
需要說明的是:
- 對于各路徑下的節點而言,其key(也就是完整路徑或名稱)需唯一。
- 對于各節點而言,會存儲該節點的value值及對應的狀态屬性,且狀态屬性至少存在一個。
二、 ZooKeeper常見節點操作
2.1 ZooKeeper的節點類型
關于ZooKeeper的節點類型如下表:
類型 | 描述 |
PERSISTENT | 表示持久節點,為預設的節點類型 |
PERSISTENT_SEQUENTIAL | 表示持久順序節點,在添加時需增加 -s 參數。該類型的節點路徑會增加序号作字尾,是以适用于分布式鎖、分布式選舉等場景。 |
EPHEMERAL | 表示臨時節點,添加時需增加- e 參數,該類型的節點不可擁有子節點,其與連接配接會話綁定,當用戶端斷開時,會由 zk 服務自動将該節點進行删除,該節點類型适用于心跳檢測,服務發現等場景。 |
EPHEMERAL_SEQUENTIAL | 表示臨時順序節點,添加節點時需增加-e, -s 參數,其特點與持久順序節點類似,差別在于其适用于會話綁定。當會話斷開後,會被自動删除。 |
CONTAINER | 表示容器節點,添加時需增加 -c 參數,當子節點全部被删除時,容器節點也會被一并進行删除 |
PERSISTENT_WITH_TTL | 表示TTL節點,建立時需添加 -t 參數,其時間為毫秒。當用戶端斷開後,不會立即删除該節點,隻有當該節點無子節點且在給定的時間内無修改時,該節點才會被删除。 |
2.2 ZooKeeper的節點的狀态屬性
對于ZooKeeper節點的狀态屬性對象Stat而言,其擁有的屬性如下所示:
狀态屬性 | 描述 |
cZxid | 表示建立該節點時對應的事務id |
ctime | 表示該節點的建立時間 |
mZxid | 表示最後修改節點時的對應的事務id |
mtime | 表示最後修改該節點的時間 |
pZxid | 表示該節點的子節點清單最後一次修改的事務id,需要說明的是,子節點清單的變更是指子節點的增加或删除,而子節點内容的修改則不屬于此範疇。 |
cversion | 表示子節點的版本号,當子節點每次被修改時,其版本号都會增1 |
dataversion | 表示資料的版本号,當資料每次被修改時,其版本号都會增1 |
aclversion | 表示權限的版本号,當權限每次被修改時,版本号都會增1 |
ephemeralOwner | 若為臨時節點,則表示會話的sessionID;若為持久節點,則該值為0 |
dataLength | 表示該節點的資料長度 |
numChildren | 表示該節點擁有的子節點的數量 |
2.3 事件監聽器Watcher
對于zookeeper的用戶端而言,其可監測 znode 節點的變化。當其發生變化時,會觸發相應的事件,并向監測節點發送通知,同時清除對該節點的監測。也就是說,在shell終端設定的Watch事件屬于一次性觸發器,當設定了監聽的資料或目錄發生改變時,伺服器會将該改變發送給設定該監聽的用戶端。下面給出一些常見的狀态:
KeeperState | EventType | 觸發條件 | 說明 | 操作 |
SyncConnected | None(-1) | 用戶端和服務端成功建立連接配接 | 此時用戶端和服務端處于連接配接狀态 | |
NodeCreated(1) | Watcher監聽的對應資料節點被建立 | Create | ||
NodeDelete(2) | Watcher監聽的對應資料節點被删除 | Delete/znode | ||
NodeDataChange(3) | Watcher監聽的對應資料節點的資料内容發生變更 | setData/znode | ||
NodeChildChange(4) | Watcher監聽的對應資料節點的子節點清單發生變更 | Create/child | ||
Disconnect(0) | None(-1) | 用戶端與ZooKeeper服務端斷開連接配接 | ||
Expired(-112) | None(-1) | 會話逾時 | 此時用戶端會話失效 | |
AuthFailed(4) | None(-1) | 通常有兩種情況:1、使用錯誤的schema進行權限驗證,2、SASL權限檢查失敗 |
下面介紹常見的監聽機制。
2.3.1 監聽節點目錄變化
監聽節點目錄變化的指令為:
ls -w 路徑
如對“test-persistent”節點進行監聽,對應指令為:
ls -w /test-persistent
執行後結果如下:
接着建立一個會話,并新增一個子節點,對應指令如下:
create /test-persistent/child-1 節點1
執行結果如下:
接着再看之前的會話,會列印如下資訊:
當再次新增節點時,該會話不會輸出新的資訊,因為該監聽是一次性的。
2.3.2 監聽節點資料變化
監聽節點資料變化的指令為:
get -w 路徑
如使用如下指令對test-persistent節點進行監聽:
get -w test-persistent
執行後如下:
接着在另一個會話中執行如下指令來修改test-persistent節點的内容:
set /test-persistent 修改測試節點資料
執行結果如下:
此時檢視之前的會話,控制台會列印如下資訊:
與之前監聽目錄變化一樣,該監聽器也為一次性。
2.4 通路控制清單ACL
所謂ACL(Acess Control List),即 ZooKeeper 的通路權限實作。其内置的schema有:
- world:此為預設方式,表示所有人都可進行通路。
- auth:這代表已認證認證的使用者(在cli中可以通過addauth digest user:pwd 來添加目前上下文中的授權使用者)
- digest:此代表使用者名:密碼認證方式。
- ip:這表示使用 ip 位址進行認證
對于ACL支援的權限如下:
- CREATE:表示能建立子節點
- READ:表示能擷取節點資料和列出子節點清單。
- WRITE:表示能設定節點資料
- DELETE:表示能删除子節點
- ADMIN:表示能設定節點的權限。
2.5 ZooKeeper用戶端常見指令
在 Zookeeper 服務啟動後,可使用如下指令來連接配接ZooKeeper服務:
./zkCli.sh -server localhost:2181
執行後結果如下所示:
zookeeper 的常見指令如下:
指令 | 描述 | 用法示例 | 說明 |
ls | 檢視某個路徑下的目錄清單 | ls [-s] [-w] [-R] path | path:完整路徑 -s:傳回狀态資訊 -w:監聽節點變化 -R:遞歸檢視某個路徑下的目錄清單 |
create | 建立節點并指派 | create [-s] [-e] [-c] [-t ttl] path [data] [acl] | -s:表示順序節點 -e:表示臨時節點,臨時節點不能有子節點 -c:表示建立的是容器節點 -t:表示建立的是ttl節點 path: 表示要建立節點的路徑 data:表示在該節點存儲的資料 acl: 表示通路的權限,預設是world |
set | 修改節點存儲的資料 | set [-s] [-v version] path data | path:表示節點的路徑 data: 表示節點需要存儲的資料 [version]: 表示版本号 |
get | 擷取節點的資料和狀态資訊 | get [-s] [-w] path | -s:傳回的結果附帶狀态資訊 -w:傳回資訊并對節點進行事件監聽 |
stat | 檢視節點狀态資訊 | stat [-w] path | path:代表路徑 -w: 表示進行事件監聽 |
delete/deleteall | 删除某節點 | delete [-v version] path deleteall path [-b batch size] | 當節點不為空的時候,無法使用該指令進行删除 |
下面介紹一下各個指令的用法。
2.5.1 檢視指令:help
檢視指令如下:
help
執行後結果如下:
2.5.2 建立永久節點指令: create
建立節點的指令為:
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
當不指定任何參數時,建立的節點即為永久節點,下面為對應的示例:
create /test testdata
執行後結果如下所示:
2.5.3 建立臨時節點指令:create -e
當需建立臨時節點時,需增加“ -e ” 參數,下面在“ /test ” 節點下建立一個臨時節點,對應的指令如下:
create -e /test/node1 aaa
執行後使用“ls /test” 指令進行檢視,結果如下:
接着執行退出指令後再次進行連接配接,并使用之前的檢視指令進行檢視,結果如下:
這表明臨時節點會在連接配接斷後會被zookeeper自動删除。
2.5.4 建立順序節點指令:create -s
若需建立順序節點,則增加 “ -s ” 參數即可。下面為對應的示例:
# 在test下建立一個node1節點
create -s /test/node1 123
# 在test下建立一個node2節點
create -s /test/node2 456
# 在同路徑下繼續建立一個同名的節點
create -s /test/node1 789
執行上面的指令後結果如下所示:
2.5.5 建立臨時順序節點:create -s -e
若需建立臨時順序節點,則需增加 " -s -e " 參數,下面為對應的示例:
create -e -s /test/node3 aaa
建立完畢後,使用對應的指令檢視結果如下所示:
退出後再次通路,使用對應的指令檢視結果如下所示:
此時發現臨時節點node3已消失不見。
2.5.6 檢視子節點清單資訊: list
檢視節點資訊的指令為:
ls [-s] [-w] [-R] path
下面給出對應的例子:
ls /
執行後結果如下所示:
2.5.7 檢視節點狀态資訊:stat
檢視節點狀态資訊的指令為:
stat[-w] path
對應的例子如下所示:
stat /zookeeper
執行結果如下所示:
2.5.8 檢視節點儲存的資訊: get
檢視節點儲存的資訊的指令為:
get [-s] [-w] path
對應的例子如下:
get /test
執行後結果如下所示:
2.5.9 修改節點的指令
下面為節點修改的指令:
set [-s] [-v version] path data
對應的例子如下所示:
set /test 1
執行後使用get -s 指令來檢視修改後的/test節點的狀态資訊,結果如下:
接着再使用set指令進行修改,修改完畢後使用get指令進行檢視,結果如下:
2.5.10 删除節點的指令
對于ZooKeeper 而言,删除指令有兩個,分别為:deleteall path [-b batch size]和delete path [version]。差別在于,deleteall 可遞歸地删除節點資訊,而對于delete而言,若當節點下存在子節點時,則無法删除該節點。
下面先驗證delete,使用到的指令為:
delete /test
執行結果如下:
接着示範deleteall,使用的指令為:
deleteall /test
接着試圖使用get指令來進行檢視,則其結果如下:
當然,除上表所列指令外,還有一些其他指令,如下圖所示: