1. 程式人生 > >ZooKeeper的Watcher機制

ZooKeeper的Watcher機制

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,會一直被儲存在客戶端 ZKWatchManagerdefaultWatcher 中。
    • ZooKeeper 客戶端也可以通過 getDataexistsgetChildren 三個介面來向 ZooKeeper 伺服器註冊 Watcher
      • 無論哪種方式,註冊 Watcher 的工作原理都是一致的。

ZooKeeper 的 Watcher 具有以下幾個特性。

  • 一次性 
    • 無論是服務端還是客戶端,一旦一個 Watcher 被觸發,ZooKeeper 都會將其從相應的儲存中移除。
    • 因此,在 Watcher 的使用上,需要反覆註冊。這樣的設計有效地減輕了服務端的壓力。
  • 客戶端序列執行 
    • 客戶端 Watcher 回撥的過程是一個串行同步的過程,這為我們保證了順序
    • 同時,需要注意的一點是,一定不能因為一個 Watcher 的處理邏輯影響了整個客戶端的 Watcher 回撥,
      • 所以,我覺得客戶端 Watcher 的實現類另開一個執行緒進行處理業務邏輯,以便給其他的 Watcher 呼叫讓出時間。
  • 輕量級
    • WatchedEvent 是最小通知單元
      • 僅僅包括:通知狀態、事件型別、節點路徑
    • 僅僅通知客戶端發生了事件,不會帶事件具體內容,具體內容需要客戶端再次請求獲取
    • 客戶端向服務端傳遞的也不是watcher 物件,使用Boolean型別標記屬性,服務端儲存當前連線的ServerCnxn

watcher 事件型別