15.4.3 ZooKeeper watches

ZooKeeper可以为所有的读操作设置watch,这些读操作包括:exists()、getChildren()以及getData()。watch事件是一次性的触发器,当watch的对象状态发生改变时,将会触发此对象上所设置的wath对应的事件。

在使用watch时需要注意,watch是一次性触发器,并且只有在数据发生改变时,watch事件才会被发送给客户端。例如:如果一个客户端进行了getData(“/znode1”,true)操作,并且之后“/znode1”的数据被改变或删除了,那么客户端将获得一个关于“/znode1”的事件。如果/znode1再次改变,那么将不再有watch事件发送给客户端,除非客户端为另一个读操作重新设置了一个watch。

watch事件将被异步地发送给客户端,并且ZooKeeper为watch机制提供了有序的一致性保证。理论上,客户端接收watch事件的时间要快于其看到watch对象状态变化的时间。

ZooKeeper所管理的watch可以分为两类:一类是数据watch(data watches);一类是子watch(child watches)。getData()和exists()负责设置数据watch, getChildren()负责设置孩子watch。我们可以通过操作返回的数据来设置不同的watch。getData()和exists()返回关于节点数据的信息,getChildren()返回孩子列表。因此,setData()将触发设置了数据watch的对应事件。一个成功的create()操作将触发Znode的数据watch,以及孩子watch。一个成功的delete()操作将触发数据watch和孩子watch,因为Znode被删除的时候,它的child watch也将被删除。

watch由客户端所连接的ZooKeeper服务器在本地维护,因此watch可以非常容易地设置、管理和分派。当客户端连接到一个新的服务器上时,任何的会话事件都将可能触发watch。另外,当从服务器断开连接的时候,watch将不会被接收。但是,当一个客户端重新建立连接的时候,任何先前注册过的watch都会被重新注册。