@xtccc
2015-10-16T10:56:51.000000Z
字数 4751
阅读 3085
ZooKeeper
Processes in a distributed system have two broad options for communication: they can exchange messages directly through a network, or read and write to some shared storage. ZooKeeper uses the shared storage model to let applications implement coordination and synchronization primitives.
znode类似于文件系统中的节点,可以是leaf node,也可以是non-leaf node。znode的path不能是相对路径,只能是绝对路径。znode的path构成,可以是满足以下条件的任意unicode字符:
The null character (\u0000) cannot be part of a path name. (This causes problems with the C binding.)
The following characters can't be used because they don't display well, or render in confusing ways: \u0001 - \u0019 and \u007F - \u009F.
The following characters are not allowed: \ud800 -uF8FFF, \uFFF0-uFFFF, \uXFFFE - \uXFFFF (where X is a digit 1 - E), \uF0000 - \uFFFFF.
The "." character can be used as part of another name, but "." and ".." cannot alone be used to indicate a node along a path, because ZooKeeper doesn't use relative paths. The following would be invalid: "/a/b/./c" or "/a/b/../c".
The token "zookeeper" is reserved.
znode可以带有少量的数据,也可以不带数据。znode如果带有数据的话,这些数据是被作为一个byte array存储的。
znode维护了一个状态结构(stat structure),包含了一个版本号,该版本号反映了数据变更、ACL变更的历史情况。此外,该stat structure还有一个timestamp。
当client从znode获取数据时,同时能获得该数据对应的version number。当client发起update或者delete的请求时,它也必须指定目标数据的version number。
每一个znode都有一个ACL(Access Control List),限制谁能做什么。
persistent znode: 只能通过
delete
删除。persistent znode可以有children。ephemeral znode:如果创建它的client崩溃了,或者client与ZK的连接过期了/关闭了,则该znode就会被删除。也可以通过
delete
删除。例如,在上图中,master与worker节点都应该是ephemeral znode。目前,ephemeral znode不能有children。
此外,znode还可以被设为 sequential 。一个sequential znode将被赋予一个独一的(相对于parent znode)、自增的整数,且该整型将被附加到指定的path后面。
因此,znode共有4种mode,分别是:persistent
,ephemeral
, persistent_sequential
,以及ephemeral_sequential
。
为了监测znode的状态变化,client需要不断地poll,这样很浪费性能。因此,ZK中引入了notificaton机制。client为某个znode设置watch,这样当该znode发生变化时,watch将会被触发,然后该watch将被清除(因此,当client收到1次通知后,应该立即设置1个新的watch)。该watch被出发后,ZK会向client发送通知。此时,client可以去读取znode的新值。
ZK produces different types of notifications, depending on how the watch corresponding to the notification was set. A client can set a watch for changes to the data of the znode, change to the children of a znode, or a node being created or deleted.
ZK中的read操作,如getData()
、getChildren()
、exists()
等,都可以选择设置watch。
每个znode都有1个version number,每当znode的数据发生变化时,这个version number都会增1。
用zkcli的命令get <znode-path>
可以发现有以下的field:
connect host:port
get path [watch]
ls path [watch]
set path data [version]
rmr path
delquota [-n|-b] path
quit
printwatches on|off
create [-s] [-e] path data acl
stat path [watch]
close
ls2 path [watch]
history
listquota path
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
setquota -n|-b val path
[zkshell: 0] ls /
[hive_zookeeper_namespace_hive, hbase, zookeeper]
[zkshell: 1] create /zk_test my_data
Created /zk_test
[zkshell: 2] ls /
[hive_zookeeper_namespace_hive, hbase, zookeeper, zk_test]
[zkshell: 3] get /zk_test
my_data
[zkshell: 4] set /zk_test junk
[zkshell: 5] get /zk_test
junk
[zkshell: 6] delete /zk_test
[zkshell: 7] ls /
[hive_zookeeper_namespace_hive, hbase, zookeeper]
详见 这篇文档
Zxid
ZK的状态每次发生变化时,都有一个相应的zxid(ZooKeeper Transaction Id)。如果 zxid1 < zxid2 ,则说明 zxid1 happens before zxid2。
Version numbers
每个znode都有相应的version numbers,包括 version
(data变化的次数),cversion
(children变化的次数),aversion
(ACL变化的次数)。
Ticks
在ZK Cluster中,server用ticks来定义事件的时间,例如status uploads、session timeouts、connection timeouts between peers,
Real time
除了当znode变化时将timestamp写入到stat structure的情况,ZK完全不使用real time / clock time
在向ZK ensemble发起任何request之前,client都必须与ZK建立session。client向ZK提交的任何操作都会与一个session绑定。
在创建session时,client只会与ZK ensemble中的某一个server建立连接。连接是基于TCP的,并且如果client有一段时间内没有收到来自已建立连接的server的心跳,该session将会自动移至另外一个server(对用户透明,由client library处理)。
同一个session内的requests可以保证满足FIFO的顺序。
一个session有4种状态:NOT_CONNECTED, CONNECTING, CONNECTED, CLOSED。
什么时候session会过期失效(expire)?
只有ZK ensemble才能宣告一个session expired,client不能。但是client可以选择close session。
如果ZK service在一个时间段内(session timeout,记为t )没有收到与该session关联的任何msg,则ZK quorum宣告该session expired。对于client,如果它在 1/3t 点处没有收到任何数据,则会向ZK server发送一条心跳消息;在 2/3t 时间点处,client就开始寻找新的server。
我们可以用以下命令让client连接到ZK Service
zkCli.sh server1:2181,server2:2181,server3:2181
其中,server1:2181,server2:2181,server3:2181
称为connect string。client会随机地选择其中的一个server去连接,如果连接失败,则会随机选择另外一个server去连接。
当当前连接的server不可用时,client会试图重新连接另外一个server。在重新连接时,新的server的状态是有要求的。如下图所示: