Zookeeper ZNode Stat对象信息解析

本文详细解析了Zookeeper中节点Stat信息的各个字段,包括cZxid/ctime、mZxid/mtime、pZxid、cversion、dataVersion、aclVersion、ephemeralOwner、dataLength和numChildren。通过实例展示了这些属性如何在节点创建、更新、添加子节点等操作中变化,强调了它们在数据一致性与版本控制中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

Zookeeper的视图结构和标准的UNIX文件系统类似,整个结构也是以树形目录结构展现的。

Zookeeper中的每个节点称为ZNode,每个ZNode上既可以保存数据,也可以挂载子节点。

关于ZNode,不仅可以存储数据,节点本身也有一些状态信息(Stat),本文就来分析下这个Stat信息。

1.Stat信息展示

我们随意创建一个节点,可以使用Zookeeper客户端命令,如下所示:

# 1.创建节点/nodefirst 并设置值为:'2022-06-19'
[zk: localhost:2181(CONNECTED) 3] create /nodefirst '2022-06-19'
Created /nodefirst

# 2.获取节点信息
[zk: localhost:2181(CONNECTED) 5] get /nodefirst
2022-06-19  # 节点值

# 以下为Stat信息
cZxid = 0x4
ctime = Sun Jun 19 15:40:10 GMT+08:00 2022
mZxid = 0x4
mtime = Sun Jun 19 15:40:10 GMT+08:00 2022
pZxid = 0x4
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 10
numChildren = 0

我们来逐个看下这些参数的含义

1.1 cZxid/ctime

cZxid即create zxid的缩写(创建该节点的事务ID),每一次事务操作都会有一个特定的zxid来代表当前事务ID。

这个值在节点创建成功后是不会变的

ctime顾名思义也就是 created time的缩写(该节点创建时间),这个值在节点创建成功后也是不会变的。

1.2 mZxid/mtime

mZxid即modified zxid的缩写(节点最后一次被更新时的事务ID),每一次更新该节点操作都会修改该值

mtime对应的也就是 modified time的缩写(节点最后一次被更新时的时间)。

那我们再来测试下,执行下set命令,看下节点信息是否修改

# 修改/nodefirst 值为 '202206191550'
[zk: localhost:2181(CONNECTED) 6] set /nodefirst '202206191550'
cZxid = 0x4
ctime = Sun Jun 19 15:40:10 GMT+08:00 2022
mZxid = 0x5
mtime = Sun Jun 19 15:50:35 GMT+08:00 2022
pZxid = 0x4
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 0

从结果可以看到,cZxid/ctime没有发生变化,而mZxid/mtime则发生了变化,mZxid增加1,mtime则为当前时间

1.3 pZxid

表示该节点的子节点列表最后一次被修改时的事务ID。

这个理解起来还是有点抽象的,直接通过示例来展示下。

# 创建节点/nodefirst 的子节点 level2_node1
[zk: localhost:2181(CONNECTED) 7] create /nodefirst/level2_node1 'node1'
Created /nodefirst/level2_node1

# 查看/nodefirst节点信息
[zk: localhost:2181(CONNECTED) 9] get /nodefirst
202206191550
cZxid = 0x4
ctime = Sun Jun 19 15:40:10 GMT+08:00 2022
mZxid = 0x5
mtime = Sun Jun 19 15:50:35 GMT+08:00 2022
pZxid = 0x6
cversion = 1
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 1

在创建子节点之前/nodefirst的pZxid=0x4,创建子节点后pZxid = 0x6

再次创建一个子节点

[zk: localhost:2181(CONNECTED) 10] create /nodefirst/level2_node2 'node2'
Created /nodefirst/level2_node2

[zk: localhost:2181(CONNECTED) 11] get /nodefirst
202206191550
cZxid = 0x4
ctime = Sun Jun 19 15:40:10 GMT+08:00 2022
mZxid = 0x5
mtime = Sun Jun 19 15:50:35 GMT+08:00 2022
pZxid = 0x7
cversion = 2
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 2

pZxid变更为0x7

那么修改子节点的值呢

[zk: localhost:2181(CONNECTED) 12] set /nodefirst/level2_node2 'node22'
cZxid = 0x7
ctime = Sun Jun 19 15:58:23 GMT+08:00 2022
mZxid = 0x8
mtime = Sun Jun 19 15:59:24 GMT+08:00 2022
pZxid = 0x7
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0

[zk: localhost:2181(CONNECTED) 13] get /nodefirst
202206191550
cZxid = 0x4
ctime = Sun Jun 19 15:40:10 GMT+08:00 2022
mZxid = 0x5
mtime = Sun Jun 19 15:50:35 GMT+08:00 2022
pZxid = 0x7
cversion = 2
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 2

pZxid=0x7,没有变化。

所以总结下来:节点的pzxid,只有子节点的列表变更了(子节点新增或删除)才会被修改,而子节点内容的变更不会影响pzxid

1.4 cversion/dataVersion/aclVersion

节点Stat信息中有三个version。

类型说明备注
dataVersion当前节点的内容版本号当前节点的内容被修改的次数。初始值为0,修改一次则增加1。内容如果没有变化,也会增加1.
cversion当前节点的子节点列表的变更版本号当前节点的子节点发生新增或删除,则版本号增加1
aclVersion当前节点的ACL变更版本号当节点的ACL控制信息,发生一次变更时,版本号增加1

综合上面的示例:

/nodefirst值被修改过一次,所以当前dataVersion=1

/nodefirst的子节点被添加过两次,所以当前cversion=2

而ACL信息,一直没有修改过,所以aclVersion=0

1.5 ephemeralOwner

创建该临时节点会话的sessionId。

如果当前节点为持久节点,那么ephemeralOwner=0。

当前/nodefirst节点就是持久节点,所以ephemeralOwner = 0x0

1.6 dataLength

这个比较容易理解,就是当前节点数据内容的长度

当前/nodefirst值为202206191550,长度就是12

1.7 numChildren

表示当前节点的子节点的数量

当前节点/nodefirst有用两个子节点

[zk: localhost:2181(CONNECTED) 14] ls /nodefirst
[level2_node2, level2_node1]

所以/nodefirst 的numChildren = 2

2.节点Stat信息的作用

实际大部分时候我们都不会直接使用到节点的Stat信息。

倒是可以使用dataVersion信息的这种特性来做一个乐观锁。

回到Zookeeper.java代码中,来看下其中的setData()方法

/**
     * @param path
     *                the path of the node
     * @param data
     *                the data to set
     * @param version
     *                the expected matching version
     */
public Stat setData(final String path, byte data[], int version)
throws KeeperException, InterruptedException {

}

这里有一个入参version,这个version就是当前我们所希望的节点的dataVersion值。

Zookeeper服务端在处理该请求时,如果发现setData请求所希望version与当前实际的version不同(节点被执行过set操作),则报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恐龙弟旺仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值