Zookeeper的数据模型类似于Unix标准文件系统,只是文件目录里面没有文件。而是统称为Znode。Znode可以存放数据,以二进制的形式(默认不超过1MB)。这样就构成了类似文件系统的层次化命名空间。其实就是树形结构。
下图是Zookeeper节点的数据模型:
Znode从持久化的角度来说,可以分类两类:
持久化节点(PERSISTENT Node):创建新增删除等操作会更新到事务日志中。
临时节点(Ephemeral Node):只存放在内存中,当该节点的Session过期或者关闭时,节点会自动删除。临时节点在有些场合可以发挥很大的作用。
注:任何临时节点的父节点不能为临时节点。
Znode从序列化的角度来说,也可以分类两类:
普通节点:节点名称由用户指定。
序列化节点(SEQUENTIAL Node):会在创建的节点名自动加上序列号,如上图,创建/app1/p_的序列化节点,例如现在只存在/app1/p_1和/app1/p_2,那么新创建的名称则为/app1/p_3.
Znode除了拥有用户定义传入的数据,还包含ACL(访问控制列表,参看:Zookeeper ACL权限控制),创建时间,修改时间,子节点个数等等数据,通过对这些数据的管理来让缓存生效并且令协调更新。每当Znode中的数据更新后它所维护的版本号将增加,这非常类似于数据库中计数器时间戳的操作方式。另外Znode还具有原子性操作的特点:命名空间中,每一个Znode的数据将被原子地读写。读操作将读取与Znode相关的所有数据,写操作将替换掉所有的数据。
节点属性(属性保存在:org.apache.zookeeper.data.Stat类中):
属性 | 描述 |
czxid | 节点被创建的zxid值 |
mzxid | 节点被修改时zxid值 |
ctime | 节点创建的时间,以Leader的时间为准,因为所有变更都是在Leader中进行的。 |
mtime | 节点最后一次的修改时间,以Leader的时间为准,因为所有变更都是在Leader中进行的。 |
vesion | 节点的版本号,每次setData都会使version+1,setData修改需要提供版本号,如果为-1,则表明在最后一个版本的基础上修改,就算发送过程中,即使被其他客户端修改了,也会自动覆盖。如果指定了版本号,那么修改不成功就会报:KeeperErrorCode = BadVersion |
cversion | 节点所拥有的子节点被修改的版本号,也就是子节点的修改次数 |
aversion | 节点的ACL被修改的版本号,也就是ACL修改的次数 |
dataLength | 节点数据的长度 |
numChildren | 节点拥有子节点的个数 |
ephemeralOwner | 如果该节点为ephemeral节点, 该值值表示与该节点绑定的session id。如果不是ephemeral节点, ephemeralOwner值为0。 |
pzxid | 父节点的zxid |