1. 核心概念

Watch 机制是 ZooKeeper 实现分布式协调的关键。它允许客户端向服务端注册一个 Watcher(监听器),当服务端指定节点的状态发生变化(如数据改变、节点删除、子节点变化)时,服务端会向客户端发送一个事件通知

这是一种发布/订阅(Publish/Subscribe)模式

2. 关键特性(面试必考)

  1. 一次性触发 (One-time trigger)
    • 这是最容易踩坑的地方。服务端发送通知后,该 Watch 就失效了。如果需要持续监听,客户端必须在处理通知的回调逻辑中再次注册 Watch。
    • 注:ZooKeeper 3.6.0+ 引入了持久监听(Persistent Watcher),但在面试中通常默认讨论经典的一次性 Watch。
  2. 推拉结合
    • ZooKeeper 的 Watch 是推(Push)模式。服务端主动推送事件通知给客户端。
    • 客户端收到通知后,通常需要主动拉(Pull)取最新的数据。
  3. 轻量级
    • 通知内容非常简单,只包含“发生了什么事件”(Event Type)和“哪个节点发生的”(Node Path),不包含变更后的具体数据。

3. 工作流程与原理

  1. 客户端注册
    • 客户端调用 getData("/node", true)exists("/node", watcher)
    • 客户端将 Watcher 对象存储在本地的 ZKWatchManager 中。
    • 客户端向服务端发送请求,标记该路径需要监听。
  2. 服务端处理
    • 服务端接收请求,将 ServerCnxn(客户端连接对象)存储在对应的 WatchManager 中。
  3. 事件触发
    • /node 数据发生变更,服务端在 WatchManager 中找到所有监听该路径的 ServerCnxn。
    • 服务端构造一个 WatchedEvent 对象,发送给客户端。
    • 服务端移除该 Watch(体现了一次性)。
  4. 客户端回调
    • 客户端收到通知,从本地 ZKWatchManager 中取出对应的 Watcher 对象。
    • 执行 Watcher 的 process() 方法。

4. 常见 Watch 事件类型

  • NodeCreated:节点创建。
  • NodeDeleted:节点删除。
  • NodeDataChanged:节点数据内容更新。
  • NodeChildrenChanged:子节点列表变化(增删子节点)。

5. 总结

面试官:请讲讲 ZooKeeper Watch 机制。

候选人: ZooKeeper 的 Watch 机制是一种基于发布/订阅模式的分布式通知机制

它的核心流程是:客户端在读取数据时(如 getData)注册 Watch,服务端记录下来。当数据发生变更时,服务端主动推送通知给客户端,客户端触发回调逻辑。

它有三个关键特性:

  1. 一次性:触发后立即失效,需要重复注册。
  2. 异步性:通知发送是异步的,不阻塞写操作。
  3. 轻量级:只通知“发生了变化”,不包含具体数据,客户端需要再次主动拉取。

这种机制非常适合用于配置中心(配置变更通知)和服务注册发现(服务上下线通知)。