欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ZK节点

程序员文章站 2024-03-24 09:41:52
...

1. ZK节点的组织

zookeeper采用树状结构对数据进行存储,整个数据存储结构非常类似于linux的文件系统。如下图所示,节点node_1的路径是/node_1,节点node_1_1的路径是/node_1/node_1_1。zookeeper就是通过对这些节点进行创建、删除、修改、读取等操作来完成系统功能的。
ZK节点

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

相关标签: zk 节点