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

发布了223 篇原创文章 · 获赞 308 · 访问量 84万+

猜你喜欢

转载自blog.csdn.net/maoyeqiu/article/details/102950220
zk