Zookeeper 的數(shù)據(jù)模型
1. 前言
開始學習 Zookeeper 的第一步,我們首先來學習 Zookeeper 的數(shù)據(jù)模型。那么我們?yōu)槭裁匆葘W習 Zookeeper 的數(shù)據(jù)模型呢?Zookeeper 的數(shù)據(jù)模型又是什么樣的呢?Zookeeper 的數(shù)據(jù)模型又有什么樣的特點呢?接下來我們就帶著這幾個問題開始 Zookeeper 的數(shù)據(jù)模型學習之旅。
2. Zookeeper 數(shù)據(jù)模型的結構
Zookeeper 數(shù)據(jù)模型的結構是基于節(jié)點的,我們把這種節(jié)點叫做 Znode ,具體結構我們來看下圖:
我們可以看見,這種結構和數(shù)據(jù)結構中的樹類似,也和文件系統(tǒng)的目錄類似。我們知道文件系統(tǒng)的引用是非常方便的,那么我們想引用 Zookeeper 某個節(jié)點,那么我們該如何引用呢?
我們可以通過路徑引用的方式來訪問 Znode 節(jié)點:
/電腦/戴爾
/手機/華為
我們來說明一下書寫規(guī)則:第 1 個 /
為根節(jié)點,電腦
為根節(jié)點的子節(jié)點,第 2 個 /
是對下一個子節(jié)點的引用,后面跟上哪個節(jié)點的名稱,就是對哪個節(jié)點的引用。
Tips: 我們對節(jié)點的引用,必須書寫全路徑,也就是說必須要從根節(jié)點開始。在 Zookeeper 底層的實現(xiàn)中,把 Znode 的絕對路徑作為 key ,Znode 本身作為 value 來保存的。使用絕對路徑來查詢也提高了 Zookeeper 的性能。
介紹完 Zookeeper 數(shù)據(jù)模型的結構,也了解了如何引用 Znode 節(jié)點,接下來我們對 Znode 節(jié)點進行詳細的講解。
3. Znode 的元素組成
我們先來了解 Znode 節(jié)點中由哪些元素組成,請看下圖:
我們可以看到,Znode 節(jié)點中由 4 種元素組成,接下來我們來分別介紹一下每個元素具體是什么。
Znode 節(jié)點元素介紹:
- data : Znode 存儲的數(shù)據(jù)信息,這里的數(shù)據(jù)指用戶保存的數(shù)據(jù);
- ACL : 對節(jié)點進行權限控制,記錄了哪些用戶或者哪些 IP 地址可以訪問本節(jié)點;
- child : 當前節(jié)點的子節(jié)點引用,通過這個節(jié)點來找到它的子節(jié)點;
- stat : 包含 Znode 的各種元數(shù)據(jù),比如事務 ID、版本號、時間戳、大小等 Znode 本身的數(shù)據(jù)。
Tips: Znode 的 data 元素存儲的信息最大不能超過 1MB 。太大的數(shù)據(jù)會影響 Zookeeper 的同步性能。
在了解了 Znode 的元素組成,每個元素的具體作用之后,我們接下來學習 Znode 節(jié)點有哪些類型,以及他們的特點。
4. Znode 的類型
本節(jié)我們來學習 Znode 的類型以及它們各自的特點。Znode 的類型分為一下 4 種:
- 持久節(jié)點: 持久節(jié)點是 Zookeeper 的默認節(jié)點,持久節(jié)點被創(chuàng)建后會一直存在,除非進行手動刪除;
- 持久順序節(jié)點: 持久順序節(jié)點是在持久節(jié)點的基礎上,增加了順序性。也就是說,持久順序節(jié)點被創(chuàng)建時,會根據(jù)創(chuàng)建的時間進行編號,根據(jù)編號我們就可以判斷它們的順序;
- 臨時節(jié)點: 臨時節(jié)點與持久節(jié)點的特點相反,臨時節(jié)點被創(chuàng)建之后,如果與創(chuàng)建它的客戶端斷開連接,臨時節(jié)點就會被銷毀;
- 臨時順序節(jié)點: 臨時順序節(jié)點就是在臨時節(jié)點的基礎上,增加了順序性。
學習了 Znode 節(jié)點的類型以及它們的特點,那么我們可以利用節(jié)點的特點做什么事情呢?接下來我們來了解節(jié)點的應用。
5. Znode 的應用
根據(jù)節(jié)點的類型以及它們的特點,我們可以實現(xiàn)以下功能:
-
我們可以使用臨時節(jié)點來實現(xiàn)服務注冊與發(fā)現(xiàn)。在某個服務注冊到 ZooKeeper 時,我們可以讓這個這個服務創(chuàng)建一個臨時節(jié)點,并把它的訪問信息交給到 Zookeeper 維護。當這個服務與 Zookeeper 斷開連接時,這個臨時節(jié)點就會被銷毀,這時 Zookeeper 發(fā)現(xiàn)這個服務離線了,就會移除它的訪問地址,避免出現(xiàn) 404 的情況。我們也可以手動刪除某個臨時節(jié)點讓相對應的服務下線;
-
當我們有大量的服務時,一旦配置信息需要修改,會消耗我們大量的時間去每個服務中修改,而且還有可能會出錯,這種情況我們就可以使用持久節(jié)點來保存全局的配置信息。當某個服務注冊到 ZooKeeper 時,可以去保存配置信息的節(jié)點讀取配置信息。當我們修改配置時,Zookeeper 會通知這些服務,服務就會重新去讀取配置信息;
-
我們可以使用臨時順序節(jié)點來實現(xiàn)分布式鎖。當多個服務同時對一個資源進行修改時,會出現(xiàn)數(shù)據(jù)錯誤,所以我們要避免這種情況。我們這里采取的方式就是為這個資源加鎖,想要獲取這個資源的服務會創(chuàng)建一個臨時順序節(jié)點,根據(jù)它的順序判斷這個臨時順序節(jié)點是否為第一個,如果是第一個則成功獲得鎖,這時這個服務就可以對這個資源進行修改了。完成操作后或者這個服務斷線了都會刪除這個節(jié)點,也就是釋放了鎖。后面的服務會根據(jù)它創(chuàng)建的臨時順序節(jié)點的順序來依次對資源進行操作。
根據(jù) Znode 特點的來實現(xiàn)的應用還有很多,后面的文章我們再詳細介紹。了解了節(jié)點的一些應用,那么我們該如何對節(jié)點進行操作呢?接下來我們就來介紹 Znode 節(jié)點的操作命令。
6. Znode 節(jié)點的操作
使用 Zookeeper 客戶端,我們可以通過以下命令來操作 Znode 節(jié)點。
-
創(chuàng)建節(jié)點:
create
# 創(chuàng)建一個持久節(jié)點 create /persistent_node # 創(chuàng)建一個持久的順序節(jié)點 create -s /persistent_sequential_node # 創(chuàng)建一個臨時節(jié)點 create -e /ephemeral_node # 創(chuàng)建一個臨時的順序節(jié)點 create -s -e /ephemeral_sequential_node
-
刪除節(jié)點:
delete
delete /config/topics/test
-
獲得一個節(jié)點的數(shù)據(jù):
get
get /persistent_node
-
設置一個節(jié)點的數(shù)據(jù):
set
set /brokers myNewData
-
獲取子節(jié)點:
ls
# 獲取根節(jié)點下的子節(jié)點 ls / # 根節(jié)點下的子節(jié)點有 zk-watcher-2,zookeeper [zk-watcher-2, zookeeper]
Tips: 我們在使用這些命令操作節(jié)點時,后面的節(jié)點必須是全路徑引用。
7. 總結
經(jīng)過上面的講解,我們知道了很多功能的實現(xiàn)都是基于 Zookeeper 的結構以及 Znode 的類型和它們的特點,所以學習 Zookeeper 的數(shù)據(jù)模型還是很有必要的?,F(xiàn)在我們來對本節(jié)的內容進行總結:
- Zookeeper 數(shù)據(jù)模型的結構為樹形節(jié)點。
- Znode 的元素組成有 4 種:data(用戶數(shù)據(jù))、ACL(權限信息)、child(子節(jié)點引用)、stat(元數(shù)據(jù))。
- Znode 的類型有 4 種:持久節(jié)點、持久順序節(jié)點、臨時節(jié)點、臨時順序節(jié)點。
- 我們可以根據(jù) Znode 的特點來實現(xiàn)各種功能,比如服務注冊與發(fā)現(xiàn)、配置中心、分布式鎖等。
- Zookeeper 客戶端操作節(jié)點的常用命令。