淺談zookeeper數據結構及實操
之前我們已經掌握了linux基礎知識,vim快速入門,linux下的軟件安裝方法以及shell基礎編程,理解了zookeeper的概念和zookeeper集羣的搭建,現在我們要深入學習zookeeper,看看他的數據結構是怎樣的,又應該怎樣操作呢?
1. 命令行客戶端
前置條件:每臺服務器的zookeeper服務均開啓且處於正常運行狀態
我們以node1節點爲例。
查看zookeeper裏的bin文件夾,其中的zkCli.sh爲命令行客戶端
在zookeeper目錄下連接客戶端:
bin/zkCli.sh
連接成功的顯示如下:
通過localhost:2181(CONNECTED) 0 可以看出當前連接的服務器是自己(node1)。
如果想連接到node2,則在命令行輸入:(我沒有配置主機名和ip的映射)
connect 192.168.159.130:2181
即可連接到node2。
我們想使用zookeeper的更多功能,可以help查看指令。
根據我們之前的zookeeper概念及架構分析,我們要清楚的是,zookeeper提供的服務只有兩大類,一類是讀寫數據,另一類就是監聽。如果這裏不明白的可以看我的另一篇博客“從幾個實例出發---理解zookeeper概念(架構分析)”,博客地址:
https://blog.csdn.net/qq_34478594/article/details/105271012
在使用zookeeper之前,我們首先需要了解zookeeper讀寫的數據長得神馬樣?不然我們就沒法讀寫它。
2 zookeeper數據結構
2.1 zookeeper的數據結構特性
1.層次化的目錄結構,命名符合常規文件系統規範。下兩張圖是我在網上找的兩張數據結構圖,不過已經足夠反應zookeeper數據結構特性了。
2.每個節點在zookeeper中叫做znode,並且有唯一的路徑標識。
3.節點znode可以包含數據和子節點(但是EPHEMERAL類型的節點不能有子節點)。
4.客戶端應用可以在節點上設置監聽器。
*** 實操***
查看根節點信息:
ls /
我們發現,根節點下有一個子節點zookeeper。它存放的是zookeeper自己的一些信息。現在我們來創建一個自己的工作節點。
create /app1 “this is app1 servers parent”
現在我們在ls一下根節點,發現多了app1節點。
ls /
我們看在app1裏還能不能在創建呢?當然可以了。我們在app1下創建server01,存放一個ip爲192.168.159.130的服務器並假設可以負載100。
create /app1/server01 “192.168.159.130,100”
我們ls一下app1的子節點。
ls /app1
也可以get到節點的數據,如現在要getserver01的數據
get /app1/server01
我們發現除了得到我們自己寫入的數據內容外還有其他的東西,他們都是節點狀態信息。
cZxid 表示節點創建時的事務id;
ctime 表示節點創建時間;
mZxid 表示節點最後一次被修改時的事務id;
mtime 表示節點最後一次被修改的時間;
pZxid 表示該節點的子節點列表最後一次被修改時的事務id。只有子節點列表變更時纔會更新pZxid,子節點的內容變更則不會更新;
cversion 表示子節點的版本號;
dataVersion 表示內容的版本號;
aclVersion 表示權限版本號;
dataLength 表示數據長度;
numChildren 表示子節點數;
ephemeralOwner表示創建該臨時節點時的會話sessionID,如果是持久性節點則值爲0。(關於節點類型後面詳細說)
2.2 節點類型
1.znode有兩種類型:
短暫(ephemeral)節點 (斷開連接時自己刪除)
持久(persistent)節點 (斷開連接不刪除)
這兩種類型的設置是很有必要的,對於zookeeper感知就是基於短暫節點的。如某臺服務器斷線,這時這臺服務器的短暫節點就會被zookeeper刪除,此時zookeeper父節點就會產生事件,因爲它發現自己的子節點減少了,從而感知到服務器掉線,並將消息發送給其他服務器讓其他服務器也收到某臺服務器掉線的消息從而做出進一步的處理。
2.znode有四種形式的目錄節點(默認是persistent)
PERSISTENT,
PERSISTENT_SEQUENTIAL(持久序列/test0000000019)
EPHEMERAL
EPHEMERAL_ SEQUENTIAL
3,創建znode時設置順序標識,znode名稱後會附加一個值,順序號是一個單調遞增的計數器,由父節點維護。
******實操******
接着上一節的實操,我們繼續。
現在我們想創建一個短暫節點。我們注意help裏給出的create指令
create [-s] [-e] path data cal
這裏的可選項[-e]就是代表短暫節點,加上就表示創建一個短暫節點。
create -e /app-ephemeral “okk”
查看根節點裏是否添加了該節點,發現已經有app-ephmeral
ls /
只要在客戶端沒有退出之前,app-ephemeral都可以工作,如我們現在get一下節點的內容
get /app-ephemeral
我們發現ephemeralOwner的值有內容了,因爲它是短暫節點。
現在我們用quit指令退出客戶端,再重新進入 /bin/zkCli.sh,此時我們再ls一下根節點,發現app-ephemeral節點被自動刪除了,驗證了上述的結論。
我們在觀察help給出的create指令create [-s] [-e] path data cal
我們發現它還有一個可選項[-s],它表示創建的節點是否帶序號 SEQUENTIAL,即對應了
PERSISTENT_SEQUENTIAL和EPHEMERAL_ SEQUENTIAL。
那麼帶序號是什麼意思呢,我們試驗一下,創建一個帶序號的節點和一個不帶序號的節點。
create /test 888
create /test/aa 999
create -s /test/bb 999
我們發現bb後面多了一串序號。且序號是自增的。這樣可以確保我們創建的每一個節點都是唯一的,不會產生衝突。
也可以更新節點,我們觀察節點更新後的節點狀態信息變化。
get /app1
set /app1 uuuu
剛纔的操作都是在同一個節點node1進行的。現在在node1節點做set更新,我們在node3節點裏啓動zookeeper客戶端,在node3中get /app1,觀察是不是app1在node3中能夠秒更新。
node3 ../zookeeper-3.4.14->
bin/zkCli.sh
node1 ->
set /app1 doUpdate
node3 ->
get /app1
我們通過實驗可以發現,數據同步的速度是實時刷新的。當集羣的節點數增加到幾十臺時,可能就會發生延遲。
我們再來觀察help提供的指令,關注 get path [watch]
我們發現我們get節點時還可以帶有watch,即zookeeper的第二大功能:監聽服務。我們通過實驗來體驗這個傳說中的監聽功能。
get /app1 watch
當數據發送變化時,客戶端就可以收到監聽通知。我們在node3中修改app1
node3 ->
set /app1 hhhhhhhh
我們在回到node1,發現有東西自動輸出,
我們發現輸出的就是app1發生修改的通知。這就是監聽功能。
我們繼續實驗,我們繼續在node3節點中修改app1.
node3 ->
set /app1 kkkk
我們回到node1,發現這次沒有輸出新內容。
我們得出結論在get /app1 watch時,我們是在獲取數據的時候註冊了一個監聽,它檢測的是當該節點數據是否發生改變,而且這個監聽只生效一次。
如果我們想監聽該節點的子節點變化,需要在獲取子節點時增加監聽
node1 ->
ls /app1 watch
我們在node3中對app1做創建子節點的操作
node3 ->
create /app1/kkk aaaaa
我們返回node1,發現自動輸出了子節點改變的監聽消息
上面介紹了兩種監聽:監聽數據發生的變化和監聽子節點的變化,這兩種也是實際工程中最常用的。
這樣我們就把zookeeper的兩大核心功能:讀寫數據和監聽談了一遍,並且通過實際操作感受了一下。相信大家跟着一起做的話,不僅能瞭解zookeeper的數據結構,也能熟悉zookeeper的命令行操作!