ZooKeeper的数据模型
摘自《apache zookeeper essentials》
维基中这样定义Zookeeper,ZooKever允许分布式进程通过数据寄存器的共享层次命名空间进行相互协调。这个命名空间和Unix文件系统非常相似,如图:
可以看到znode
是分层次管理的,更像是一棵树,或者是标准的文件系统,一些关键点:
- 根结点只有一个
child znode
叫/zoo
,反之,/zoo
有三个child znode
- ZooKeeper树中的每个结点都是以
path
为标识,并且path
是通过/
分割 znode
被称为是数据寄存器,因为可以存储数据,因此一个znode
可以是children
也可以和数据相关联,就像文件系统中的文件可以是路径
znode
中的数据通常以二进制的格式存储,并且znode
的数据大小不能超过1MB
,ZooKeeper被设计成用来协调的,并且所通知协调的数据量相对较小,所以对数据量的限制是强制的,强烈推荐实际数据量大小应小于这个限制。
znode的类型
ZooKeeper中有两种类型的znode:持久(persistent)和短暂(ephemeral),也有第三种类型,或许你可能听过,叫做sequential
znode,其他两种类型的限定词,persistent
和ephemeral
类型的znode也可以是sequential
类型,注意,znode的类型在创建的时候就被设置了
持久znode(the persistent znode)
顾名思义,持久的znode在Zookeeper中具有生存期,除非显示的将其删除。可以调用delete
API去删除一个znode,不是只有客户端创建的znode可以被删除,只要在Zookeeper服务中被授权的客户端都可以删除znode
[zk: localhost:2181(CONNECTED) 5] create /say "hello"
Created /say
[zk: localhost:2181(CONNECTED) 6] get /say
hello
cZxid = 0xc
ctime = Mon Jul 09 13:49:56 UTC 2018
mZxid = 0xc
mtime = Mon Jul 09 13:49:56 UTC 2018
pZxid = 0xc
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 7]
这种类型的znode是不会随着创建客户端的灭亡而一起消失的
短暂类型的znode(The ephemeral znode)
与之相反的,一个短暂类型的znode会被ZooKeeper servie
删除如果客户端的session已经结束的话。结束客户端session有可能是客户端的宕机导致的失去连接,或者是显示的中断了连接。虽然短暂类型的znode和客户端的session紧密相关,但是仍然对其他的客户端可见,这要依赖于配置的ACL
(Access Control List
)策略.
一个短暂类型的znode可以由创建的客户端显示的删除,或者任何其他已经授权的客户端通过调用delete
API删除,因此,当前版本的ZooKeeper
短暂类型的znode是不允许有子结点的,创建一个短暂类型的znode只需要在创建(create)的时候加入参数-e
即可:
[zk: localhost:2181(CONNECTED) 4] create -e /ephemeralnode "ephemeral"
Created /ephemeralnode
[zk: localhost:2181(CONNECTED) 5] create -e /ephemeralnode/child "ephemeral-child"
Ephemerals cannot have children: /ephemeralnode/child
短暂类型的理念可以被用在那些组件需要了解其他组件或者资源的状态的分布式应用中,比如一个group membership
服务就可以使用短暂的znode来实现
有序类型znode(The sequential znode)
有序类型的znode被创建的时候,ZooKeeper
会分配一个有序的数字作为名字的一部分,这个数字会一直增加并添加到znode名称的后面(由父znode维护)。用来存储有序数字的计数器是有符的整型(4个字节),十位数字,不足补0,如znode-0000000001
,这样的命名约束是为了排序znode
有序可以用来实现分布式全局队列(
distributed global queue
),因为有序的数字强制全局是有序的。也可以在分布式应用中用来实现锁服务(lock service
)
因为persistent
和ephemeral
类型的znodes可以是sequential
类型的znode,这样就有了以下组合:
- persistent
- ephemeral
- persistent_sequential
- ephemeral_sequential
使用create
命令创建有序类型的znode:
[zk: localhost:2181(CONNECTED) 0] ls /
[hello, zookeeper, root]
[zk: localhost:2181(CONNECTED) 1] create -s /persistent_sequential "p_sequential"
Created /persistent_sequential0000000005
[zk: localhost:2181(CONNECTED) 2] create -s -e /ephemeral_sequential "e_sequential"
Created /ephemeral_sequential0000000006
[zk: localhost:2181(CONNECTED) 3] ls /
[persistent_sequential0000000005, hello, ephemeral_sequential0000000006, zookeeper, root]