ZooKeeper說話的方式簡單點

文/小碼農談IT

簡單點,說話的方式簡單點。縈繞耳畔的是這首歌,那就簡單點吧,來淺談一下ZooKeeper的理解。小馬仍然努力尋求以最通俗的語言來一起入門理解下這個分散式利器。

啥是ZooKeeper

ZooKeeper是一個分散式的,開放原始碼的分散式應用程式協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要元件。它是一個為分散式應用提供一致性服務的軟體,提供的功能包括:配置維護、域名服務、分散式同步、組服務等。

以上是百科的解釋,其實ZooKeeper的功能包括

資料釋出/訂閱,負載均衡,命名服務,分散式協調/通知,叢集管理,Master選舉,分散式鎖和分散式佇列

等。它還是Kafka等中介軟體的重要依賴元件呢。它為啥這麼優秀呢?還得從它的原理說起。下文將以zk簡稱ZooKeeper

為什麼ZooKeeper能做這麼多

ZooKeeper的工作原理可以簡單歸結為兩個詞:

檔案系統+監聽機制

。是的,你沒看錯,它就是這麼得簡單粗暴。

1、檔案系統

我們借用一張圖來直觀理解一下。

ZooKeeper說話的方式簡單點

每個根目錄下的子目錄節點,都被稱作為 znode(目錄節點)。和檔案系統一樣,能做各種增刪改查操作,唯一的不同是znode是可以儲存資料的。

有四種節點型別:

永久節點(persistent):客戶端與zk斷開連線後,該節點依舊存在,除非客戶端主動刪除;

臨時節點(ephemeral):客戶端關閉zk連線後自動清除,此型別不能有子節點;

有編號節點(Persistent_sequential):自動增加順序編號的znode持久化節點;

臨時有編號(Ephemral_ sequential):znode節點編號會自動增加,但是是臨時的,會隨客戶端連線斷開而消失。分散式鎖建立的鎖節點就是這種。

2、監聽機制

客戶端註冊監聽它關心的目錄節點,當目錄節點發生變化(資料改變、節點刪除、子目錄節點增刪)時,zk會通知客戶端。這其實有點像訂閱釋出機制,這個機制對zk命名服務,分散式協調/通知,叢集管理,分散式佇列等的實現至關重要。其監聽過程下面配置中心再作詳細說明,先借用一張圖來助於理解。

ZooKeeper說話的方式簡單點

ZooKeeper能做什麼

我們就以比較經典的配置中心和分散式鎖功能來簡單理解下ZooKeeper是怎麼做到的。

1、配置中心

我們還是借用一張圖來助於理解。

ZooKeeper說話的方式簡單點

其中大概的流程是這樣,zookeeper service是一個配置中心服務,底下的三個為客戶端服務,服務啟動後,由ConfigFetcher模組(可以認為是客戶端服務上的zk客戶端程式碼塊)和zookeeper service通訊,獲取它所關心的znode目錄節點中的配置資料(可以考慮同步儲存一份到本地配置檔案來維護,當配置中心服務掛掉後可以取本地配置),並向該znode節點註冊一個watcher以監聽節點資料的變更。當ConfigUpdater(可以做成一個管理後臺中心)對zookeeper service中的配置資料進行變更,各個服務受到節點配置資料變動通知,讀取新的配置資料,並重新註冊watcher以監聽下一次變更。其實很像釋出訂閱機制,監聽機制的作用在這裡得到充分發揮。

小馬聯想到consul的配置中心,不過小馬的理解是其是基於consul叢集內部的客戶端資料同步。

2、分散式鎖

分散式鎖是最經常被談及的一個話題,zk的分散式鎖還是要得益於它的臨時有序號接節點,當然監聽機制是基礎。還是借用下一張圖來助於理解吧。

ZooKeeper說話的方式簡單點

參照上圖,我們想要實現一個分散式鎖,比如秒殺資源鎖。首先建立一個永續性節點test/lock。每個需要獲取秒殺鎖的執行緒進來後都會建立一個臨時有序節點,比如A使用者建立了test/lock/seq-0000 0001節點,B建立了test/lock/seq-0000 0002節點。由於有序性,我們規定編號最小的節點獲得到鎖,可以進行秒殺操作,操作完釋放鎖就是刪除節點。我們的B在A釋放鎖之前處於等待狀態,等待A的znode節點的通知,一旦被刪除,就進行再一次判斷,如果自己現在是最小的那個節點則獲得鎖,可以秒殺操作了。因此,這裡每一個等通知的znode節點,只需要監聽linsten或者watch監視排號在自己前面那個znode節點就可以了。

這種一傳一的監聽方式,可以避免羊群效應,就是假如A被刪除,其他的所有節點都同時去監聽變化做出反應造成伺服器壓力。這樣也就很好理解為什麼要使用臨時的有序節點(失去連線刪除節點釋放鎖)而不是永久的,因為一傳一的方式如果其中一個斷掉,不釋放鎖,那麼後面都會斷掉,一直等待導致死鎖。

ZooKeeper說話的方式簡單點

後記

zk一般以叢集的方式出現,一般包含三個角色,leader,follower,observer,內建Master選舉機制,這點和consul叢集內部選舉功能類似。zk中建立和刪除節點只能透過Leader伺服器來執行,然後Leader伺服器還需要將資料同步到所有的Follower機器上。每次在建立鎖和釋放鎖的過程中,都要動態建立、銷燬瞬時節點來實現鎖功能,高併發下影響效能。所以通常在高併發量,效能要求很高的場景下,被推薦使用基於redis的分散式鎖,而可靠性要求高的場景使用zk。

就此擱筆吧。本文主要是小馬的個人學習理解,分享整理出來旨在希望能有助於大家理解zk,不到之處還請指正。深入實踐請參閱官方文件,本文部分資料參考於網路資源,感謝分享者無私分享。