Zookeeper Watch
概要:zookeeper watch为了对znode数据变更时间进行监听。客户端在使用zookeeper接口访问zookeeper时,如果注册了watch实例,那么当zookeeper znode节点有数据变更时,zkserver会发送watchevent给客户端,发送完后watch实例将移除,wath时间只发生异常,如需要再次监听,客户端需要注册watch实例到zkserver端。zookeeper目前只支持监听事件一次发送。
zkserver watch只能接受一次watchevent分析
客户端分析:
对zookeeper源码分析可以发现Zookeeper类实现客户端对zkserver进行访问,ClientCnxn类实现了客户端对zkserver访问的链接处理,Zookeeper.ZKWatchManager实现对服务端发送过来的watchevent pack数据解析。ClientCnxn中的SendThread复制接受zkserver发送过来的watchevent数据处理,在处理的过程中对使用Zookeeper.ZKWatchManager的materialize方法对发送过来的wathevent数据进行解析转换成Watch实例。zkserver在znode数据发送变化时,实际会连续发送3个事件:SyncConnected -> DataNodeChanged -> Close。再看meterialize代码可见,meterialize方法会在第一 个事件发送完后的事件对zookeeper实例中的watchset中的watch清除。所以在客户端处理完后之前注册watch实例不生效。
![](https://img.haomeiwen.com/i14034711/4b1624413535a083.png)
![](https://img.haomeiwen.com/i14034711/d78289ad187577cc.png)
![](https://img.haomeiwen.com/i14034711/7bbc7a002437db47.png)
服务端分析:
LeaderZookeeperServer负责,LeaderRequestProcessor、PreRequestProcessor、ProposalRequestProcessor、CommitProcessor
、FinalRequestProcessor实现对客户端发送过来的pack数据处理。对FinalRequestProcessor类进行分析可以发现:
![](https://img.haomeiwen.com/i14034711/bdc7bf48b3189417.png)
zkserver会在ZKDatabase实例中注入watch实例并将watch实例注入到DataTree中。对DataTree进行分析可以发现,当数据发生变化时,会触发数据变事件:
![](https://img.haomeiwen.com/i14034711/218c58b53c769770.png)
dataWatches childWatches实际上是WatchManager的实例,对WatchManager实例进行分析可以发现:
![](https://img.haomeiwen.com/i14034711/a7241690bdfc36f0.png)
综上所述:
客户端在watchevent事件发生后会将watch实例移除,服务端也会将watch实例移除。所以watch事件只是一次生效。
网友评论