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

數據模型node

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

Znode:bash

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

Snip20171125_108.png

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

Snip20171125_109.png

Znode具備以下特性:分佈式

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

  • 數據訪問:ZK上存儲的數據須要被原子性的操做(要麼修改爲功要麼回到原樣),也是就讀操做將會讀取節點相關全部數據,寫操做也會修改節點相關全部數據,,並且每一個節點都有本身的ACL。spa

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

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

  • 臨時順序節點(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

相關文章
相關標籤/搜索