1. watch概述
ZooKeeper可以為所有的讀操作設(shè)置watch,這些讀操作包括:exists()、getChildren()及getData()。
watch事件是一次性的觸發(fā)器,當(dāng)watch的對(duì)象狀態(tài)發(fā)生改變時(shí),將會(huì)觸發(fā)此對(duì)象上watch所對(duì)應(yīng)的事件。
watch事件將被異步地發(fā)送給客戶端,并且ZooKeeper為watch機(jī)制提供了有序的一致性保證。
理論上,客戶端接收watch事件的時(shí)間要快于其看到watch對(duì)象狀態(tài)變化的時(shí)間。
2. watch類型
ZooKeeper所管理的watch可以分為兩類:
- 數(shù)據(jù)watch(data watches):getData和exists負(fù)責(zé)設(shè)置數(shù)據(jù)watch;
- 孩子watch(child watches):getChildren負(fù)責(zé)設(shè)置孩子watch;
可以通過(guò)操作返回的數(shù)據(jù)來(lái)設(shè)置不同的watch:
- getData和exists:返回關(guān)于節(jié)點(diǎn)的數(shù)據(jù)信息;
- getChildren:返回孩子列表;
因此:
- 一個(gè)成功的setData操作將觸發(fā)Znode的數(shù)據(jù)watch;
- 一個(gè)成功的create操作將觸發(fā)Znode的數(shù)據(jù)watch以及孩子watch;
- 一個(gè)成功的delete操作將觸發(fā)Znode的數(shù)據(jù)watch以及孩子watch;
3.watch注冊(cè)與觸發(fā)

- exists操作上的watch,在被監(jiān)視的Znode創(chuàng)建、刪除或數(shù)據(jù)更新時(shí)被觸發(fā)。
- getData操作上的watch,在被監(jiān)視的Znode刪除或數(shù)據(jù)更新時(shí)被觸發(fā)。在被創(chuàng)建時(shí)不能被觸發(fā),因?yàn)橹挥衂node一定存在,getData操作才會(huì)成功。
- getChildren操作上的watch,在被監(jiān)視的Znode的子節(jié)點(diǎn)創(chuàng)建或刪除,或是這個(gè)Znode自身被刪除時(shí)被觸發(fā)。可以通過(guò)查看watch事件類型來(lái)區(qū)分是Znode,還是他的子節(jié)點(diǎn)被刪除:NodeDelete表示Znode被刪除,NodeDeletedChanged表示子節(jié)點(diǎn)被刪除。
watch由客戶端所連接的ZooKeeper服務(wù)器在本地維護(hù),因此watch可以非常容易地設(shè)置、管理和分派。當(dāng)客戶端連接到一個(gè)新的服務(wù)器 時(shí),任何的會(huì)話事件都將可能觸發(fā)watch。另外,當(dāng)從服務(wù)器斷開(kāi)連接的時(shí)候,watch將不會(huì)被接收。但是,當(dāng)一個(gè)客戶端重新建立連接的時(shí)候,任何先前注冊(cè)過(guò)的watch都會(huì)被重新注冊(cè)。
4.注意事項(xiàng)
Zookeeper的watch實(shí)際上要處理兩類事件:
- 連接狀態(tài)事件(type=None, path=null):這類事件不需要注冊(cè),也不需要我們連續(xù)觸發(fā),我們只要處理就行了。
- 節(jié)點(diǎn)事件:節(jié)點(diǎn)的建立,刪除,數(shù)據(jù)的修改。它是one time trigger,我們需要不停的注冊(cè)觸發(fā),還可能發(fā)生事件丟失的情況。
上面2類事件都在watch中處理,也就是重載的process(Event event)
節(jié)點(diǎn)事件的觸發(fā),通過(guò)函數(shù)exists,getData或getChildren來(lái)處理這類函數(shù),有雙重作用:1.注冊(cè)觸發(fā)事件;2.函數(shù)本身的功能。
函數(shù)的本身的功能又可以用異步的回調(diào)函數(shù)來(lái)實(shí)現(xiàn),重載processResult()過(guò)程中處理函數(shù)本身的的功能。