- 为什么添加Watch
ZooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调内核,用户可以在此之上构建更多复杂的分布式协调功能。
多个分布式进程通过ZooKeeper提供的API来操作共享的ZooKeeper内存数据对象ZNode来达成某种一致的行为或结果,这种模式本质上是基于状态共享的并发模型,与Java的多线程并发模型一致,他们的线程或进程都是”共享式内存通信“。Java没有直接提供某种响应式通知接口来监控某个对象状态的变化,只能要么浪费CPU时间毫无响应式的轮询重试,或基于Java提供的某种主动通知(Notif)机制(内置队列)来响应状态变化,但这种机制是需要循环阻塞调用。而ZooKeeper实现这些分布式进程的状态(ZNode的Data、Children)共享时,基于性能的考虑采用了类似的异步非阻塞的主动通知模式即Watch机制,使得分布式进程之间的“共享状态通信”更加实时高效,其实这也是ZooKeeper的主要任务决定的—协调。Consul虽然也实现了Watch机制,但它是阻塞的长轮询。
- ZooKeeper VS JVM
从某种角度来说,可以这样对比(个人看法,可以讨论),ZooKeeper对等于JVM,ZooKeeper包含状态对象(ZNode)和分布式进程的底层执行引擎Zab,而JVM内部包含堆(多线程共享的大量对象存放区域)和多线程执行正确性约束规范JMM(Java内存模型),JMM确保了多线程的执行顺序是正确的。Zab协议使得ZooKeeper的内部修改状态操作直接是有序串行的,而JVM内部则是乱序并行的,需要添加额外的机制才能保证时序(内存屏障、处理器原子指令),而状态读取时,JVM和ZooKeeper都存在直接读取时读到旧数据,但ZooKeeper有Watch机制使得响应式读取更高效,而JVM只能使用底层的内存屏障刷新共享状态,以便其他线程再次读取时获得正确的新数据。
ZooKeeper提供的接口使得所有的分布式进程的执行都是异步非阻塞的(WaitFree算法),内部是基于Version的CAS操作,而JVM提供了阻塞的和非阻塞的多种接口,有Synchronized、Volatile、AtomicOperations。基于接口之上构建线程或分布式进程之间更复杂的同步或协调功能时,Java并发库直接提供了闭锁、循环栅栏、信号量等同步工具以及基础的抽象队列同步器,而ZooKeeper则需要用户基于接口自行构建各种分布式协调功能(分布式锁、分布式发布订阅、集群成员关系管理)。如下图:
ZooKeeper | JVM | |
共享状态对象 | ZNode | 堆中对象 |
底层执行模式 | Zab顺序执行 | 多处理器并发执行(内存屏障、原子机器指令) |
API接口 | Get、Watch_Get、Cas_Set、Exist | Synchronized、volatile、final、Atomic |
协调或同步功能 | 分布式发布订阅、锁、读写锁 | 并发库同步工具、基于抽象队列同步器构建的同步组件 |
- ZooKeeper的Watch架构
Watch的整体流程如下图所示,客户端先向ZooKeeper服务端成功注册想要监听的节点状态,同时客户端本地会存储该监听器相关的信息在WatchManager中,当ZooKeeper服务端监听的数据状态发生变化时,ZooKeeper就会主动通知发送相应事件信息给相关会话客户端,客户端就会在本地响应式的回调相关Watcher的Handler。
- ZooKeeper的Watch特性
- Watch是一次性的,每次都需要重新注册,并且客户端在会话异常结束时不会收到任何通知,而快速重连接时仍不影响接收通知。
- Watch的回调执行都是顺序执行的,并且客户端在没有收到关注数据的变化事件通知之前是不会看到最新的数据,另外需要注意不要在Watch回调逻辑中阻塞整个客户端的Watch回调
- Watch是轻量级的,WatchEvent是最小的通信单元,结构上只包含通知状态、事件类型和节点路径。ZooKeeper服务端只会通知客户端发生了什么,并不会告诉具体内容。
- Watcher接口设计
如上图所示,Watch被设计成一个接口,任何实现了Watcher接口的类就是一个新的Watcher,Watcher内部包含2个枚举类,一个KeeperState,表示当事件发生时ZooKeeper的状态,另一个是事件发生的类型,主要分为2类(一类是ZNode内容的变化,另一类是ZNode子节点的变化),具体的描述见下表。
KeeperState |
EventType | TriggerCondition | EnableCalls | Desc |
SyncConnected (3)
|
None (-1) |
客户端与服务器成功建立会话 | 此时客户端与服务器处于连接状态 | |
同上 |
NodeCreated (1) |
Watcher监听的对应数据节点被创建 | Exists | 同上 |
同上 |
NodeDeleted (2) |
Watcher监听的对应数据节点被删除 | Exists, GetData, and GetChildren | 同上 |
同上 |
NodeDataChanged (3) |
Watcher监听的数据节点的数据内容和数据版本号发生变化 | Exists and GetData | 同上 |
同上 |
NodeChildrenChanged (4) |
Watcher监听的数据节点的子节点列表发生变化,子节点内容变化不会触发 | GetChildren | 同上 |
Disconnected (0) |
None (-1) |
客户端与ZooKeeper服务器断开连接 | 此时客户端与服务器处于断开连接的状态 | |
Expried (-112) |
None (-1) |
会话超时 | 此时客户端会话失效,通常同时也会收到SessionExpiredException异常 | |
AuthFailed (4) |
None (-1) |
通常有两种情况: 1.使用错误的scheme进行权限检查 2.SASL权限检查失败 |
收到AuthFailedException异常 |
- WatchEvent的设计
如上图所示,WatchEvent有2种表示模式,一种是逻辑表示即WatchedEvent,是直接封装了各种抽象的逻辑状态(KeeperState,EventType),适用于客户端和服务端各自内部处理,另一种是物理表示即封装的更多是底层基础的传输数据结构(int,String),并且实现了序列化接口,主要用来做底层的数据传输。
相关推荐
主要介绍了zookeeper watch机制的相关内容,内容比较详细,需要的朋友可以参考下。
1.ZooKeeper 是什么? 2.ZooKeeper 提供了什么? 3.Zookeeper 文件系统 4.四种类型的 znode 5.Zookeeper 通知机制 6.Zookeeper 做了什么? 7.zk 的命名服务(文件系统) ...23.zookeeper watch 机制
记录一些简单示例和偶尔的思绪 ...思考 Zookeeper Watch 机制,对 cloud 服务进行优化? ps:听说最近 Spring Cloud Alibaba 对 openfeign 和 Dubbo 做了兼容,采用降级调用 openfeign 假装 FeignAutoConfiguration F
通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向ZooKeeper服务器发送请求并接受响应,同时还能够通过该连接接收来自服务器的Watch事件通知。Session的sessionTimeout值用来设置一个客户端...
在某个消费者故障或者重启等情况下,其他消费者会感知到这一变化(通过 zookeeper watch消费者列表),然后重新进行负载均衡,保证所有的分区都有消费者进行消费。 命名服务(Naming Service) 命名服务也是分布式...
zkclient 项目项目介绍:zkclient 是对zookeeper java客户端进行的封装,主要实现了连接、断线重连,watch事件改为listen监听事件,分布式锁等注意: 使用时需要自行编译安装到maven或打成jar使用使用方式:...
zookeeper的master 选举机制? ! zookeeper主从复制机制? ! zookeeper的典型使用场景有哪些? ! zookeeper分布式集群管理? ! zookeeper分布式注册中心? ! zookeeper分布式JOB? ! zookeeper分布式锁? ! zookeeperZAP...
* WATCH, MULTI, EXEC, DISCARD事务机制实现分布式锁 * SETNX实现分布式锁 * 锁的释放 2. 使用Memcached实现分布式锁 3. 使用ZooKeeper实现分布式锁 获取锁 释放锁 获取锁 释放锁 Spring Cloud面试题 什么是 Spring ...
更新:支持指定renew时间renew(ttl=3)待修复的问题:针对etcd key 加入watch机制,解决客户端意外退出没有释放锁的问题.曾经写过关于分布式互斥锁的文章:zookeeper:redis:安装方法git clone ...
(3)watch dog自动延期机制 (4)可重入加锁机制 (5)锁释放机制 (6)此种方案Redis分布式锁的缺陷 一、写在前面 现在面试,一般都会聊聊分布式系统这块的东西。通常面试官都会从服务框架(Spring Cloud...
Controller在Zookeeper的/brokers/ids节点上注册Watch。一旦有Broker宕机(本文用宕机代表任何让Kafka认为其Brokerdie的情景,包括但不限于机器断电,网络不可用,GC导致的StopTheWorld,进程crash等),其在...
所以出现了很多优秀的JAVA中间件(JMS,memcache等,千万不要把网站做成一个数据库系统),对于上述的配置场景zookeeper是目前为止最适合也是使用程度最广的技术,其提供的一致性解决方案和watch机制解决了配置管理...