Zookeeper原理

Zookeeper主要用在分佈式應用中實現一致性協調調度服務。它的命名空間類似傳統文件系統,每個節點都以唯一的路徑進行標識,不同的是,每個節點除了可以擁有子節點外,還可擁有相對性的data數據。

一、Zookeeper命名空間

上圖是一個典型的Zookeeper命名空間結構,通過路徑"/app1/p_1"可訪問znode1節點,每個節點可存儲少量數據,如狀態、配置、位置信息等等,且data信息量很小,一般在byte到KB級別。節點znode維護一個狀態stat結構(包括數據變化的版本號、ACL變化、時間戳),以允許緩存驗證與協調更新。每當節點數據內容改變時,多一個版本號,類似HBase。客戶端獲取數據的同時也獲取相對應的版本號。節點數據內容以原子方式讀寫,讀操作會讀取該znode的全部data數據,同樣寫操作也會覆蓋該znode的全部data數據,不存在部分讀寫的情況。同時,每個節點有一個訪問控制列表ACL(Access Control List)來約束訪問操作,即具有權限控制。

znode存在兩種:

常規的znode: 由用戶顯式創建和刪除

ephemeral znode:臨時型znode, 其生命週期伴隨於創建它的session, session結束後,ZooKeeper Server會自動刪除它,當然用戶也可以顯式的刪除

 

二、Zookeeper的Watches

Zookeeper對Node的增刪改查都可觸發監聽,每個client可對一個znode設置一個watch事件。當watch監視的數據發生變化時,會通知設置了該watch的client,即watcher。watch事件是一次性觸發器,即觸發一次就會被取消,該client如果還要監視該znode的變化,需要再次設置相應的watch事件。

注:

watch事件異步發送至觀察者,可能導致當兩次觸發時間間隔太短的時候,不同的接收者收到的事件不一致

watch是一次性觸發的且在獲取watch事件和設置watch事件之間有延遲,所以不能可靠的觀察到節點的每一次變化

客戶端監視一個節點,總是先獲取watch事件,再發現節點的數據變化。
watch事件的順序對應於zookeeper服務所見的數據更新順序

 

三、Zookeeper讀寫流程

讀請求到來時,將直接從replicated database獲取數據,replicated database是一個內存數據庫,因此讀寫效率高

寫請求到來時,所有的寫請求都會先發送給一個稱之爲leader的server,然後由該leader廣播給各個follower(server),在收到超過一半的server反饋的ack之後,認爲此次寫操作成功。同時,再寫操作更新到內存數據庫之前,會先持久化到磁盤,用於恢復。如下圖所示:

 

四、在dubbo中的應用

在分佈式系統中,通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源或服務的地址,提供者等信息。被命名的實體通常可以是集羣中的機器,提供的服務地址,遠程對象等等——這些我們都可以統稱他們爲名字(Name)。其中較爲常見的就是一些分佈式服務框架中的服務地址列表。通過調用ZK提供的創建節點的API,能夠很容易創建一個全局唯一的path,這個path就可以作爲一個名稱。比如dubbo應用中:

服務提供者在啓動的時候,向ZK上的指定節點/dubbo/${serviceName}/providers目錄下寫入自己的URL地址,這個操作就完成了服務的發佈。

服務消費者啓動的時候,訂閱/dubbo/serviceName/providersURL/dubbo/serviceName/providers目錄下的提供者URL地址,並向/dubbo/{serviceName} /consumers目錄下寫入自己的URL地址。

注意,所有向ZK上註冊的地址都是臨時節點,這樣就能夠保證服務提供者和消費者能夠自動感應資源的變化。

另外,Dubbo還有針對服務粒度的監控,方法是訂閱/dubbo/${serviceName}目錄下所有提供者和消費者的信息。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章