Zookeeper詳解(三):Zookeeper中的Znode特性

數據模型

ZK擁有一個命名空間就像一個精簡的文件系統,不同的是它的命名空間中的每個節點擁有它自己或者它下面子節點相關聯的數據。ZK中必須使用絕對路徑也就是使用“/”開頭。

Znode:

ZK目錄樹中每個節點對應一個Znode。每個Znode維護這一個屬性,當前版本、數據版本、建立時間和修改時間等,看下圖:

Snip20171125_108.png

ZK就是使用這些屬性來實現特殊功能的。當一個客戶端要對某個節點進行修改時,必須提供該數據的版本號,當節點數據發生變化是其版本號就會增加。如下圖:

Snip20171125_109.png

Znode具有如下特性:

  • Watches:客戶端可以在節點上設置Watches(可以叫做監視器)。當節點狀態發生變化時,就會觸發監視器對應的操作,當監視器被觸發時,ZK服務器會向客戶端發送且只發送一個通知

  • 數據訪問:ZK上存儲的數據需要被原子性的操作(要麼修改成功要麼回到原樣),也是就讀操作將會讀取節點相關所有數據,寫操作也會修改節點相關所有數據,,而且每個節點都有自己的ACL。

節點類型:ZK中有幾種節點類型,節點類型在節點創建的時候就被確定且不可改變

  • 臨時節點(EPHEMERAL):臨時創建的,會話結束節點自動被刪除,也可以手動刪除,臨時節點不能擁有子節點

  • 臨時順序節點(EPHEMERAL_SEQUENTIAL):具有臨時節點特徵,但是它會有序列號,分佈式鎖中會用到該類型節點

  • 持久節點(PERSISTENT):創建後永久存在,除非主動刪除。

  • 持久順序節點(PERSISTENT_SEQUENTIAL):該節點創建後持久存在,相對於持久節點它會在節點名稱後面自動增加一個10位數字的序列號,這個計數對於此節點的父節點是唯一,如果這個序列號大於2^32-1就會溢出。

創建順序節點

create -s /NODE_NAME DATA    # -e參數爲創建臨時節點,如果不帶參數則創建持久節點

Snip20171125_110.png

ZK中的時間和版本號:

ZXID:ZK節點狀態改變會導致該節點收到一個zxid格式的時間戳,這個時間戳是全局有序的,每次更新都會產生一個新的。如果zxid1的值小於zxid2,那麼說明zxid2發生的改變在zxid1之後。zxid是一個唯一的事務ID,具有遞增性,一個znode的建立或者更新都會產生一個新的zxid值,具體時間有3個cZxid(節點創建時間)、mZxid(該節點修改時間,與子節點無關)、pZxid(該節點的子節點的最後一次創建或者修改時間,孫子節點無關)

version:對節點的每次操作都會使節點的版本號增加,有三個版本號dataversion(數據版本號)、cversion(子節點版本號)、aclversion(節點所擁有的ACL版本號)

Snip20171125_111.png

cZxid
創建節點時的事務ID
ctime
創建節點時的時間
mZxid
最後修改節點時的事務ID
mtime
最後修改節點時的時間
pZxid
表示該節點的子節點列表最後一次修改的事務ID,添加子節點或刪除子節點就會影響子節點列表,但是修改子節點的數據內容則不影響該ID
cversion
子節點版本號,子節點每次修改版本號加1
dataversion
數據版本號,數據每次修改該版本號加1
aclversion
權限版本號,權限每次修改該版本號加1
dataLength
該節點的數據長度
numChildren
該節點擁有子節點的數量


版本號的作用

Zookeeper裏面的版本號和我們理解的版本號不同,它表示的是對數據節點的內容、子節點列表或者ACL信息的修改次數。節點創建時dataversion、aclversion,cversion都爲0,每次修改響應內容其對應的版本號加1。

這個版本號的用途就和分佈式場景的一個鎖概念有關。比如演出售票中的一個座位,顯然每個場次中的每個座位都只有一個,不可能賣出2次。如果A下單的時候顯示可售,他想買,那麼爲了保證他可以下單成功,此時別人就不能買。這時候就需要有一種機制來保證同一時刻只能有一個人去修改該座位的庫存。這就用到了鎖。鎖有悲觀鎖和樂觀鎖。

  • 悲觀鎖:它會假定所有不同事務的處理一定會出現干擾,數據庫中最嚴格的併發控制策略,如果一個事務A正在對數據處理,那麼在整個事務過程中,其他事務都無法對這個數據進行更新操作,直到A事務釋放了這個鎖。

  • 樂觀鎖:它假定所有不同事務的處理不一定會出現干擾,所以在大部分操作裏不許加鎖,但是既然是併發就有出現干擾的可能,如何解決衝突就是一個問題。在樂觀鎖中當你在提交更新請求之前,你要先去檢查你讀取這個數據之後該數據是否發生了變化,如果有那麼你此次的提交就要放棄,如果沒有就可以提交。

Zookeeper中的版本號就是樂觀鎖,你修改節點數據之前會讀取這個數據並記錄該數據版本號,當你需要更新時會攜帶這個版本號去提交,如果你此時攜帶的版本號(就是你上次讀取出來的)和當前節點的版本號相同則說明該數據沒有被修改過,那麼你的提交就會成功,如果提交失敗說明該數據在你讀取之後和提交之前這段時間內被修改了。

這裏通過set命令並攜帶版本號提交更新,版本號相同更新就會成功。

Snip20180624_92.png

如果你再次更新並使用之前的版本號那麼就會失敗。

Snip20180624_93.png


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