ZK節點

1. ZK節點的組織

zookeeper採用樹狀結構對數據進行存儲,整個數據存儲結構非常類似於linux的文件系統。如下圖所示,節點node_1的路徑是/node_1,節點node_1_1的路徑是/node_1/node_1_1。zookeeper就是通過對這些節點進行創建、刪除、修改、讀取等操作來完成系統功能的。
在這裏插入圖片描述

2. ZK節點的數據結構

cZxid = 0x300000002
ctime = Thu Dec 08 23:29:53 CST 2011
mZxid = 0xe00008bbf
mtime = Thu Jul 28 07:17:34 CST 2012
pZxid = 0x300000002
cversion = 0
dataVersion = 2164293
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 39
numChildren = 0

在zookeeper中,每次對數據節點的寫操作都是一個事務,每個事務都有一個唯一的事務id作爲這個事務的標識。

  • cZxid就是創建這個節點的事務id。每個Zookeeper狀態的變化都以zxid(事務ID)的形式接收到標記。這個暴露了Zookeeper所有變化的總排序。每個變化都會有一個zxid,並且如果zxid1早於zxid2則zxid1一定小於zxid2。
  • ctime是創建這個節點的時間。
  • mZxid是最後更新該節點的事務id。
  • mtime是節點被最後更新的時間。
  • pZxid是節點的子節點列表被最後一次更新的事務id。子節點列表被更新只有兩種情況,分別是“增加子節點”和“刪除子節點”。修改子節點的數據內容不包括在內。
  • cversion是當前節點的子節點的變更版本號。
  • dataVersion當前節點存儲數據內容的變更版本號。
  • aclVersion當前數據節點acl的變更版本號。上面3個版本號均可以用於實現樂觀鎖。
  • ephemeralOwner爲創建該臨時節點的事務id。如果是持久節點,那麼該值固定爲0。
  • dataLength表示當前節點存儲數據內容的長度。
  • numChildren表示當前節點包含的子節點個數。

3. 節點的類型

Znode有四種類型,PERSISTENT(持久節點)、PERSISTENT_SEQUENTIAL(持久的連續節點)、EPHEMERAL(臨時節點)、EPHEMERAL_SEQUENTIAL(臨時的連續節點),Znode的類型在創建時確定並且之後不能再修改

3.1. 臨時節點

臨時節點的生命週期和客戶端會話綁定。也就是說,如果客戶端會話失效,那麼這個節點就會自動被清除掉。臨時節點不能有子節點

String root = "/ephemeral";
String createdPath = zk.create(root, root.getBytes(),
          Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("createdPath = " + createdPath);

String path = "/ephemeral/test01" ; 
createdPath = zk.create(path, path.getBytes(),
            Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("createdPath = " + createdPath);
Thread.sleep(1000 * 20); // 等待20秒關閉ZooKeeper連接
zk.close(); // 關閉連接後創建的臨時節點將自動刪除

3.2. 持久節點

所謂持久節點,是指在節點創建後,就一直存在,直到有刪除操作來主動清除這個節點——不會因爲創建該節點的客戶端會話失效而消失。

String root = "/computer";
String createdPath = zk.create(root, root.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("createdPath = " + createdPath);

3.3. 臨時順序節點

臨時節點的生命週期和客戶端會話綁定。也就是說,如果客戶端會話失效,那麼這個節點就會自動被清除掉。注意創建的節點會自動加上編號。

String root = "/ephemeral";
String createdPath = zk.create(root, root.getBytes(),
          Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("createdPath = " + createdPath);

String path = "/ephemeral/test01" ; 
createdPath = zk.create(path, path.getBytes(),
            Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("createdPath = " + createdPath);
Thread.sleep(1000 * 20); // 等待20秒關閉ZooKeeper連接
zk.close(); // 關閉連接後創建的臨時節點將自動刪除

3.4. 持久順序節點

這類節點的基本特性和持久節點類型是一致的。額外的特性是,在ZooKeeper中,每個父節點會爲他的第一級子節點維護一份時序,會記錄每個子節點創建的先後順序。基於這個特性,在創建子節點的時候,可以設置這個屬性,那麼在創建節點過程中,ZooKeeper會自動爲給定節點名加上一個數字後綴,作爲新的節點名。這個數字後綴的範圍是整型的最大值。

String root = "/computer";
String createdPath = zk.create(root, root.getBytes(),
       Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("createdPath = " + createdPath);
for (int i=0; i<5; i++) {
   String path = "/computer/node";
   String createdPath = zk.create(path, path.getBytes(),
       Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
   System.out.println("createdPath = " + createdPath);
}
zk.close();

4. 節點刪除的時機

兩個場景下會刪除:第一、用戶自己手動觸發;第二、session過期

通過下邊這兩個命令就可以把節點刪除

delete path [version] :加版本號則會選擇刪除選中版本的節點,不加則直接刪除節點。(有子節點無法刪除)
rmr path :此命令用於強制刪除當前節點以及子節點

對應的Java代碼:

        //同步刪除節點
        zk.delete("/testRoot/children", -1);   
        //異步刪除節點
        zk.delete("/testRoot/children", -1, new AsyncCallback.VoidCallback() {
            @Override
            public void processResult(int rc, String path, Object ctx) {
                System.out.println("rc====="+rc);
                System.out.println("path======"+path);
                System.out.println("ctc======"+path);
            }
        } , "回調值");

參考文章:

http://arganzheng.life/zookeeper-introduction.html

https://dawn-jt.github.io/2018/12/16/Zookeeper/Zookeeper%E6%89%AB%E7%9B%B2/

https://segmentfault.com/a/1190000012070655

https://www.hollischuang.com/archives/1280

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章