1. 分布式锁
总结:
其实如果有客户端C、客户端D等N个客户端争抢一个zk分布式锁,原理都是类似的。大家都是上来直接创建一个锁节点下的一个接一个的临时顺序节点,如果自己不是第一个节点,就对自己上一个节点加监听器只要上一个节点释放锁,自己就排到前面去了,相当于是一个排队机制。
而且用临时顺序节点的另外一个用意就是,如果某个客户端创建临时顺序节点之后,不小心自己宕机了也没关系,zk感知到那个客户端宕机,会自动删除对应的临时顺序节点,相当于自动释放锁,或者是自动取消自己的排队。
2.Znode特性
ZK目录树中每个节点对应一个Znode。每个Znode维护这一个属性,当前版本、数据版本、建立时间和修改时间等,如下图:
1.Watches:客户端可以在节点上设置Watches(可以叫做监视器)。当节点状态发生变化时,就会触发监视器对应的操作,当监视器被触发时,ZK服务器会向客户端发送且只发送一个通知
2.数据访问:ZK上存储的数据需要被原子性的操作(要么修改成功要么回到原样),也是就读操作将会读取节点相关所有数据,写操作也会修改节点相关所有数据,,而且每个节点都有自己的ACL。
3.节点类型:ZK中有几种节点类型,节点类型在节点创建的时候就被确定且不可改变
-
- 临时节点:临时创建的,会话结束节点自动被删除,也可以手动删除,临时节点不能拥有子节点
-
- 临时顺序节点:具有临时节点特征,但是它会有序列号,分布式锁中会用到该类型节点
-
- 持久节点:创建后永久存在,除非主动删除。
-
- 持久顺序节点:该节点创建后持久存在,相对于持久节点它会在节点名称后面自动增加一个10位数字的序列号,这个计数对于此节点的父节点是唯一,如果这个序列号大于2^32-1就会溢出。
3. Watch
a.一次性触发
事件发生触发监听,一个 watcher event 就会被发送到设置监听的客户端,这种效果是一次性的,后续再次发生同样的事件,不会再次触发。
b. 事件封装
ZooKeeper 使用 WatchedEvent 对象来封装服务端事件并传递。
WatchedEvent 包含了每一个事件的三个基本属性: 通知状态,事件类型和节点路径。
c. event 异步发送
watcher 的通知事件从服务端发送到客户端是异步的。
d. 先注册再触发
Zookeeper 中的 watch 机制,必须客户端先去服务端注册监听,这样事件发送才会触发监听,通知给客户端。