ZooKeeper的Watcher機制
阿新 • • 發佈:2018-11-26
ZooKeeper 提供了分散式資料的釋出/訂閱功能。
- 在 ZooKeeper 中,引入了 Watcher 機制來實現這種分散式的通知功能。
- ZooKeeper 允許客戶端向服務端註冊一個 Watcher 監聽,
- 當伺服器的一些特定事件觸發了這個 Watcher,那麼就會向指定客戶端傳送一個事件通知來實現分散式的通知功能。
- Watcher 機制主要包括客戶端執行緒、客戶端 WatchManager 和 ZooKeeper 伺服器三部分。
- - ZooKeeper :部署在遠端主機上的 ZooKeeper 叢集,當然,也可能是單機的。
- Client :分佈在各處的 ZooKeeper 的 jar 包程式,被引用在各個獨立應用程式中。
- WatchManager :一個介面,用於管理各個監聽器,只有一個方法 materialize(),返回一個 Watcher 的 set。
在具體流程上(簡單講),
- 客戶端在向 ZooKeeper 伺服器註冊 Watcher 的同時,會將 Watcher 物件儲存在客戶端的 WatchManager 中。
- 當ZooKeeper 伺服器觸發 Watcher 事件後,會向客戶端傳送通知,
- 客戶端執行緒從 WatchManager 的實現類中取出對應的 Watcher 物件來執行回撥邏輯。
工作機制
- Watcher 機制,總的來說可以分為三個過程:客戶端註冊 Watcher、伺服器處理 Watcher 和客戶端回撥 Watcher,
- 其內部各元件之間的關係如圖:
- 在建立一個 ZooKeeper 客戶端物件例項時,可以向構造方法中傳入一個預設的 Watcher:
- 這個 Watcher 將作為整個 ZooKeeper會話期間的預設 Watcher,會一直被儲存在客戶端 ZKWatchManager 的 defaultWatcher 中。
- ZooKeeper 客戶端也可以通過 getData、exists 和 getChildren 三個介面來向 ZooKeeper 伺服器註冊 Watcher
- 無論哪種方式,註冊 Watcher 的工作原理都是一致的。
ZooKeeper 的 Watcher 具有以下幾個特性。
- 一次性
- 無論是服務端還是客戶端,一旦一個 Watcher 被觸發,ZooKeeper 都會將其從相應的儲存中移除。
- 因此,在 Watcher 的使用上,需要反覆註冊。這樣的設計有效地減輕了服務端的壓力。
- 客戶端序列執行
- 客戶端 Watcher 回撥的過程是一個串行同步的過程,這為我們保證了順序,
- 同時,需要注意的一點是,一定不能因為一個 Watcher 的處理邏輯影響了整個客戶端的 Watcher 回撥,
- 所以,我覺得客戶端 Watcher 的實現類要另開一個執行緒進行處理業務邏輯,以便給其他的 Watcher 呼叫讓出時間。
- 輕量級
- WatchedEvent 是最小通知單元
- 僅僅包括:通知狀態、事件型別、節點路徑
- 僅僅通知客戶端發生了事件,不會帶事件具體內容,具體內容需要客戶端再次請求獲取
- 客戶端向服務端傳遞的也不是watcher 物件,使用Boolean型別標記屬性,服務端儲存當前連線的ServerCnxn
- WatchedEvent 是最小通知單元
watcher 事件型別