Zookeeper提供了数据的发布/订阅功能,多个订阅者可同时监听某一特定主题对象,当该主题对象的自身状态发生变化时(例如节点内容改变、节点下的子节点列表改变等),会实时、主动通知所有订阅者。
watcher实现原理
框架实现如下图:
1、zk客户端向zk服务器注册watcher的同时,会将watcher对象存储在客户端的watchManager。 2、Zk服务器触发watcher事件后,会向客户端发送通知,客户端线程从watchManager中回调watcher执行相应的功能。
watcher触发的事件
两种watch类型:结点的watch和子结点的watch
4种watch触发事件类型:NodeCreated、NodeDeleted、NodeDataChanged、NodeChildrenChanged
创建结点 | 创建子结点 | 删除结点 | 删除子结点 | 设置值 | |
exists | NodeCreated | NodeDeleted | NodeDataChanged | ||
getData | NodeDeleted | NodeDataChanged | |||
getChildren | NodeChildrenChanged | NodeDeleted | NodeChildrenChanged |
watch只能触发一次,如果需要多次收到通知,客户端需要重新注册watch
- 当watch的znode被创建、删除或数据被更新时(无论数据是否改变),设置在exists上的事件被触发
- 当watch的znode被删除或数据被更新时。设置在getData上的事件被触发
- 当watch的childrenznode被创建或删除时,设置在getChildren上的事件被触发
测试exists操作
[zk: zk02:2181(CONNECTED) 0] ls / [zookeeper] [zk: zk02:2181(CONNECTED) 1] stat -w /abc Node does not exist: /abc [zk: zk02:2181(CONNECTED) 2] create /abc "a" WATCHER::Created /abc WatchedEvent state:SyncConnected type:NodeCreated path:/abc [zk: zk02:2181(CONNECTED) 3] set /abc 'a' [zk: zk02:2181(CONNECTED) 4] stat -w /abc cZxid = 0x10000000a ctime = Sun Mar 07 06:24:56 EST 2021 mZxid = 0x10000000b mtime = Sun Mar 07 06:51:18 EST 2021 pZxid = 0x10000000a cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 1 numChildren = 0 [zk: zk02:2181(CONNECTED) 5] set /abc 'a' WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/abc [zk: zk02:2181(CONNECTED) 6] stat -w /abc cZxid = 0x10000000a ctime = Sun Mar 07 06:24:56 EST 2021 mZxid = 0x10000000c mtime = Sun Mar 07 06:51:32 EST 2021 pZxid = 0x10000000a cversion = 0 dataVersion = 2 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 1 numChildren = 0 [zk: zk02:2181(CONNECTED) 8] stat -w /abc cZxid = 0x10000000a ctime = Sun Mar 07 06:24:56 EST 2021 mZxid = 0x10000000c mtime = Sun Mar 07 06:51:32 EST 2021 pZxid = 0x10000000a cversion = 0 dataVersion = 2 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 1 numChildren = 0 [zk: zk02:2181(CONNECTED) 9] set /abc 'a' WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/abc [zk: zk02:2181(CONNECTED) 10] stat -w /abc cZxid = 0x10000000a ctime = Sun Mar 07 06:24:56 EST 2021 mZxid = 0x10000000d mtime = Sun Mar 07 06:52:46 EST 2021 pZxid = 0x10000000a cversion = 0 dataVersion = 3 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 1 numChildren = 0
[zk: zk02:2181(CONNECTED) 11] delete /abc
WATCHER::
WatchedEvent state:SyncConnected type:NodeDeleted path:/abc
测试getData
[zk: zk02:2181(CONNECTED) 37] get -w /a a [zk: zk02:2181(CONNECTED) 38] set /a 'a' [zk: zk02:2181(CONNECTED) 39] WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/a
测试getChildren
[zk: zk02:2181(CONNECTED) 42] ls -w /a [] [zk: zk02:2181(CONNECTED) 43] create /a/b 'b' WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/a Created /a/b [zk: zk02:2181(CONNECTED) 44] delete /a/b WATCHER:: WatchedEvent state:SyncConnected type:NodeDeleted path:/a/b WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/a