Zookeeper Watch
概要:zookeeper watch為了對(duì)znode數(shù)據(jù)變更時(shí)間進(jìn)行監(jiān)聽(tīng)。客戶端在使用zookeeper接口訪問(wèn)zookeeper時(shí),如果注冊(cè)了watch實(shí)例,那么當(dāng)zookeeper znode節(jié)點(diǎn)有數(shù)據(jù)變更時(shí),zkserver會(huì)發(fā)送watchevent給客戶端,發(fā)送完后watch實(shí)例將移除,wath時(shí)間只發(fā)生異常,如需要再次監(jiān)聽(tīng),客戶端需要注冊(cè)watch實(shí)例到zkserver端。zookeeper目前只支持監(jiān)聽(tīng)事件一次發(fā)送。
zkserver watch只能接受一次watchevent分析
客戶端分析:
對(duì)zookeeper源碼分析可以發(fā)現(xiàn)Zookeeper類實(shí)現(xiàn)客戶端對(duì)zkserver進(jìn)行訪問(wèn),ClientCnxn類實(shí)現(xiàn)了客戶端對(duì)zkserver訪問(wèn)的鏈接處理,Zookeeper.ZKWatchManager實(shí)現(xiàn)對(duì)服務(wù)端發(fā)送過(guò)來(lái)的watchevent pack數(shù)據(jù)解析。ClientCnxn中的SendThread復(fù)制接受zkserver發(fā)送過(guò)來(lái)的watchevent數(shù)據(jù)處理,在處理的過(guò)程中對(duì)使用Zookeeper.ZKWatchManager的materialize方法對(duì)發(fā)送過(guò)來(lái)的wathevent數(shù)據(jù)進(jìn)行解析轉(zhuǎn)換成Watch實(shí)例。zkserver在znode數(shù)據(jù)發(fā)送變化時(shí),實(shí)際會(huì)連續(xù)發(fā)送3個(gè)事件:SyncConnected -> DataNodeChanged -> Close。再看meterialize代碼可見(jiàn),meterialize方法會(huì)在第一 個(gè)事件發(fā)送完后的事件對(duì)zookeeper實(shí)例中的watchset中的watch清除。所以在客戶端處理完后之前注冊(cè)watch實(shí)例不生效。



服務(wù)端分析:
LeaderZookeeperServer負(fù)責(zé),LeaderRequestProcessor、PreRequestProcessor、ProposalRequestProcessor、CommitProcessor
、FinalRequestProcessor實(shí)現(xiàn)對(duì)客戶端發(fā)送過(guò)來(lái)的pack數(shù)據(jù)處理。對(duì)FinalRequestProcessor類進(jìn)行分析可以發(fā)現(xiàn):

zkserver會(huì)在ZKDatabase實(shí)例中注入watch實(shí)例并將watch實(shí)例注入到DataTree中。對(duì)DataTree進(jìn)行分析可以發(fā)現(xiàn),當(dāng)數(shù)據(jù)發(fā)生變化時(shí),會(huì)觸發(fā)數(shù)據(jù)變事件:

dataWatches childWatches實(shí)際上是WatchManager的實(shí)例,對(duì)WatchManager實(shí)例進(jìn)行分析可以發(fā)現(xiàn):

綜上所述:
客戶端在watchevent事件發(fā)生后會(huì)將watch實(shí)例移除,服務(wù)端也會(huì)將watch實(shí)例移除。所以watch事件只是一次生效。