Zookeeper Watcher 機制詳解


1、Watcher 機制:

  Zookeeper 允許客戶端向服務端的某個 Znode 注冊一個 Watcher 監聽,當服務端的一些指定事件觸發了這個 Watcher,服務端會向指定客戶端發送一個事件通知來實現分布式的通知功能,然后客戶端根據 Watcher 通知狀態和事件類型做出業務上的改變。

工作機制:(1)客戶端注冊 watcher(2)服務端處理 watcher(3)客戶端回調 watcher

2、Watcher 特性:

(1)一次性無論是服務端還是客戶端,一旦一個 Watcher 被 觸 發 ,Zookeeper 都會將其從相應的存儲中移除。這樣的設計有效的減輕了服務端的壓力,不然對於更新非常頻繁的節點,服務端會不斷的向客戶端發送事件通知,無論對於網絡還是服務端的壓力都非常大。

(2)客戶端串行執行客戶端 Watcher 回調的過程是一個串行同步的過程。

(3)輕量

  3.1、Watcher 通知非常簡單,只會告訴客戶端發生了事件,而不會說明事件的具體內容。

  3.2、客戶端向服務端注冊 Watcher 的時候,並不會把客戶端真實的 Watcher 對象實體傳遞到服務端,僅僅是在客戶端請求中使用 boolean 類型屬性進行了標記。

(4)watcher event 異步發送 watcher 的通知事件從 server 發送到 client 是異步的,這就存在一個問題,不同的客戶端和服務器之間通過 socket 進行通信,由於網絡延遲或其他因素導致客戶端在不通的時刻監聽到事件,由於 Zookeeper 本身提供了 ordering guarantee,即客戶端監聽事件后,才會感知它所監視 znode發生了變化。所以我們使用 Zookeeper 不能期望能夠監控到節點每次的變化。Zookeeper 只能保證最終的一致性,而無法保證強一致性。

(5)注冊 watcher getData、exists、getChildren

(6)觸發 watcher create、delete、setData

(7)當一個客戶端連接到一個新的服務器上時,watch 將會被以任意會話事件觸發。當與一個服務器失去連接的時候,是無法接收到 watch 的。而當 client 重新連接時,如果需要的話,所有先前注冊過的 watch,都會被重新注冊。通常這是完全透明的。只有在一個特殊情況下,watch 可能會丟失:對於一個未創建的 znode的 exist watch,如果在客戶端斷開連接期間被創建了,並且隨后在客戶端連接上之前又刪除了,這種情況下,這個 watch 事件可能會被丟失。

3、客戶端注冊 Watcher 實現

(1)調用 getData()/getChildren()/exist()三個 API,傳入 Watcher 對象

(2)標記請求 request,封裝 Watcher 到 WatchRegistration

(3)封裝成 Packet 對象,發服務端發送 request

(4)收到服務端響應后,將 Watcher 注冊到 ZKWatcherManager 中進行管理

(5)請求返回,完成注冊。

4. 服務端處理 Watcher 實現

(1)服務端接收 Watcher 並存儲接收到客戶端請求,處理請求判斷是否需要注冊 Watcher,需要的話將數據節點的節點路徑和 ServerCnxn(ServerCnxn 代表一個客戶端和服務端的連接,實現了 Watcher 的 process 接口,此時可以看成一個 Watcher 對象)存儲在WatcherManager 的 WatchTable 和 watch2Paths 中去。

(2)Watcher 觸發以服務端接收到 setData() 事務請求觸發 NodeDataChanged 事件為例:

  2.1 封裝 WatchedEvent將通知狀態(SyncConnected)、事件類型(NodeDataChanged)以及節點路徑封裝成一個 WatchedEvent 對象

  2.2 查詢 Watcher從 WatchTable 中根據節點路徑查找 Watcher

  2.3 沒找到;說明沒有客戶端在該數據節點上注冊過 Watcher2.4 找到;提取並從 WatchTable 和 Watch2Paths 中刪除對應 Watcher(從這里可以看出 Watcher 在服務端是一次性的,觸發一次就失效了)

(3)調用 process 方法來觸發 Watcher這里 process 主要就是通過 ServerCnxn 對應的 TCP 連接發送 Watcher 事件通知。

5. 客戶端回調 Watcher

客戶端 SendThread 線程接收事件通知,交由 EventThread 線程回調 Watcher。客戶端的 Watcher 機制同樣是一次性的,一旦被觸發后,該 Watcher 就失效了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM