ZooKeeper的整体结构使用层级的命名空间,很像一个文件系统,树上的节点称为znode,znode的路径是它的唯一标识,znode存储应用的数据,客户端通过接口获取和更新znode的数据,也可以监听znode的变化。根据应用场景的不同,存在多种不同类型的znode,包括临时节点、序列节点和容器节点。ZooKeeper不使用服务端时间来保序,提供了多种保序的方式。
znode
每个Znode都维护了一个表示节点状态的数据结构,包括版本号和时间戳,每次znode的数据改变,都会导致版本号增加。版本号用于控制节点的状态更新,每次ZooKeeper的客户端获取数据时,都会得到数据的版本号,当客户端试图更新或删除数据时,它必须提供数据的版本号,如果它提供的版本号和当前的版本号匹配,则操作成功,否则操作失败。
znode的基本属性如下:
zxid
见”Zxid“。
- czxid:该znode被创建时改变的zxid;
- mzxid:该znode最后被修改时改变的zxid;
- pzxid:该znode最后被修改的孩子节点改变的zxid;
时间
见”服务端时间“。
- ctime:该znode被创建时的毫秒值;
- mtime:该znode最后被修改时的毫秒值;
版本
见”版本号“。
- version:该znode的数据的改变次数;
- cversion:该znode的孩子改变的次数;
- aversion:该znode的ACL改变的次数;
节点类型
见”临时节点“。
- ephemeralOwner:如果该znode为一个临时节点,该值为znode的拥有者的session id;如果不是一个临时节点,值为零;
其它
- dataLength:该znode的数据的长度;
- numChildren:该znode的孩子的个数。
监听(watches)
ZooKeeper的客户端能够监听zonde的变化,当znode变化时,ZooKeeper会发送通知消息到客户端。请参考后续的监听章节。
数据存取
存储在znode上的数据被原子的读和写,读请求将读取znode上的所有数据,而写则是替换znode上的所有数据,每个znode都有一个访问控制表(ACL)来限制谁能做什么。
ZooKeeper不能被当作一个通用数据库或存储大量数据,它仅应该被用来管理协作数据,通常要求这些协作数据应该较小:千字节规模。ZooKeeper的客户端和服务端都会限制znode的数据不会超过1M,但znode上的数据的平均值应该更小。限制数据大小的主要原因是为了防止数据同步时的时间过长。
如果确实需要存储大量数据,通常的解决方案是存储该数据到第三方存储系统中,例如NFS或者HDFS等,再将数据的指针存储到ZooKeeper中。
znode类型
临时节点(Ephemeral Node)
临时节点和ZooKeeper的session绑定,ZooKeeper客户端通过session创建znode临时节点后,只要该session不断开,znode临时节点就存在,而当session断开后,znode临时节点将被删除。
临时节点不允许存在孩子节点。
序列节点(Sequence Node)
在创建一个znode时,你能要求ZooKeeper为Znode添加一个序号,该序号对于该znode的父节点是唯一的。序号的格式为%010d,固定格式是为了简化对znode的排序。
注意序号是一个有符号的整数,超出范围后将溢出。
容器节点(Container Node)
3.6.0版本增加。
容器节点是为leader、lock等操作存在的,当容器节点的最后一个孩子节点被删除之后,容器节点将被标注并在一段时间后删除。
由于容器节点的该特性,当你在容器节点下创建一个孩子节点时,应该始终准备捕获KeeperException.NoNodeException,如果捕获了该异常,则需要重新创建容器节点。
ZooKeeper中的时序
ZooKeeper使用多种方式来跟踪时序:
Zxid(ZooKeeper Transaction Id)
对ZooKeeper的每次状态改变都会收到一个zxid的时间戳,zxid反应了对zookeeper的所有改变的顺序,每次改变都有一个唯一的zxid,并且如果zxid1小于zxid2,那么zxid1发生在zxid2之前。
zxid分为两个部分,epoch和counter。epoch用于标识对应的leader,每次新的leader产生,epoch加1;counter用于对状态改变计数,每次状态改变counter加1。
版本号
每个znode都有一个版本号,每次对该znode的改变都会导致该znode的版本号的增加。有3种类型的版本号:
- version:znode的数据改变的次数;
- cversion:znode的孩子改变的次数;
- aversion:znode的ACL改变的次数。
Ticks
当使用多节点的ZooKeeper时,ticks表示事件的次数,事件包括:状态上载、session超时、节点间的连接超时等。
服务端时间
除了znode的创建时间和修改时间使用服务端,ZooKeeper不使用服务端时间作为时序的保障。