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
推荐阅读
-
EXT 2个tree节点拖拽都是 (转) EXTCC++C#J#
-
<el-tree> 解决勾选会把父节点下的子节点全部勾选的问题
-
ZK节点
-
动态加载有子节点的树 json
-
openstack-nova-compute.service 计算节点服务无法启动
-
161.OpenStack_Train版-12.安装块存储服务cinder(控制节点)
-
(四)Eureka Server用户认证(双节点为例)
-
Nginx实战系列之功能篇----后端节点健康检查 博客分类: sa_运维_network_硬件
-
使用MPICH构建一个四节点的集群系统 博客分类: 网站架构 应用服务器Linux网络应用电子商务软件测试
-
【以太坊】- 私有节点