zk的客户端命令:
create [-s] [-e] path data acl
:-s代表顺序节点,-e代表临时节点,什么都不加则是持久节点。ls path [watch]
:[watch]代表是否需要监控。get path [watch]
:[watch]代表是否需要监控。set path data [version]
:[version]代表版本,节点是有版本的概念的,基于哪个版本进行数据更新。delete path [version]
:基于哪个版本进行节点删除。
删除节点接口的权限控制比较特殊,当客户端对一个数据节点添加了权限信息后,对于删除操作来说,其作用范围是其子节点,也就是说,当我们对一个数据节点添加权限信息后,依然可以自由地删除这个节点,但是对于这个节点的子节点,就必须使用相应的权限信息才能够删除掉它。
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
zkclient
是将原生ZK的api进行封装,剔除了Watcher
,使用Listener
。而且Listener一次注册一直有效,Watcher需要反复注册。zkclient支持递归
的操作,原生的api不支持递归操作。
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.4.2</version>
</dependency>
curator
是另一个zk客户端,支持递归,同时它提供了fluent风格的api。此外,Curator中还提供了ZK各种应用场景(Recipe,如共享锁服务,master选举机制和分布式计数器等)的抽象封装。
ZK中的节点有版本的概念,可以基于版本进行数据的更新,节点的删除等,类似于CAS,传入一个版本号,看现在的真实版本是否和其一致,如果一致进行操作,不一致不操作。
临时节点不能创建子节点。
ZK的发布/订阅
采用的是推和拉
相结合的模式:客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变化,那么服务端就会向相应的客户端发送Watcher事件通知,客户端接收到这个消息通知以后,需要主动到服务端获取最新的数据。
ZK中,每个数据节点称为一个ZNode
,所有ZNode按层次化结构进行组织,形成一棵树,ZNode的节点路径标识方式和Unix
文件系统路径非常相似,都是由一系列使用斜杠(/)进行分割的路径表示,可以向节点中写入数据,也可以在节点下面创建子节点。
乐观锁控制的事务分成如下三个阶段:数据读取
,写入校验
,数据写入
。比如CAS校验是否是预期值,Zookeeper中的version。
Zookeeper服务器在生成WatchedEvent事件之后,会调用getWrapper方法将事件包装成一个可序列化的WatcherEvent
事件,这里明显使用了装饰器模式。
CONNECTION_LOSS
是指客户端和服务端因为网络等原因断开连接,断开连接之后客户端会进行连接重试,如果重连成功,那服务端的session不更换,之前的Watcher和临时节点也都存在;如果在会话超时时间过后还没有连接成功,则SESSION_EXPIRED
,服务端会清理session,watcher以及临时节点。