您好,登錄后才能下訂單哦!
數據模型
ZK擁有一個命名空間就像一個精簡的文件系統,不同的是它的命名空間中的每個節點擁有它自己或者它下面子節點相關聯的數據。ZK中必須使用絕對路徑也就是使用“/”開頭。
Znode:
ZK目錄樹中每個節點對應一個Znode。每個Znode維護這一個屬性,當前版本、數據版本、建立時間和修改時間等,看下圖:
ZK就是使用這些屬性來實現特殊功能的。當一個客戶端要對某個節點進行修改時,必須提供該數據的版本號,當節點數據發生變化是其版本號就會增加。如下圖:
Znode具有如下特性:
Watches:客戶端可以在節點上設置Watches(可以叫做監視器)。當節點狀態發生變化時,就會觸發監視器對應的操作,當監視器被觸發時,ZK服務器會向客戶端發送且只發送一個通知
數據訪問:ZK上存儲的數據需要被原子性的操作(要么修改成功要么回到原樣),也是就讀操作將會讀取節點相關所有數據,寫操作也會修改節點相關所有數據,,而且每個節點都有自己的ACL。
節點類型:ZK中有幾種節點類型,節點類型在節點創建的時候就被確定且不可改變
臨時節點(EPHEMERAL):臨時創建的,會話結束節點自動被刪除,也可以手動刪除,臨時節點不能擁有子節點
臨時順序節點(EPHEMERAL_SEQUENTIAL):具有臨時節點特征,但是它會有序列號,分布式鎖中會用到該類型節點
持久節點(PERSISTENT):創建后永久存在,除非主動刪除。
持久順序節點(PERSISTENT_SEQUENTIAL):該節點創建后持久存在,相對于持久節點它會在節點名稱后面自動增加一個10位數字的序列號,這個計數對于此節點的父節點是唯一,如果這個序列號大于2^32-1就會溢出。
創建順序節點
create -s /NODE_NAME DATA # -e參數為創建臨時節點,如果不帶參數則創建持久節點
ZK中的時間和版本號:
ZXID:ZK節點狀態改變會導致該節點收到一個zxid格式的時間戳,這個時間戳是全局有序的,每次更新都會產生一個新的。如果zxid1的值小于zxid2,那么說明zxid2發生的改變在zxid1之后。zxid是一個唯一的事務ID,具有遞增性,一個znode的建立或者更新都會產生一個新的zxid值,具體時間有3個cZxid(節點創建時間)、mZxid(該節點修改時間,與子節點無關)、pZxid(該節點的子節點的最后一次創建或者修改時間,孫子節點無關)
version:對節點的每次操作都會使節點的版本號增加,有三個版本號dataversion(數據版本號)、cversion(子節點版本號)、aclversion(節點所擁有的ACL版本號)
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命令并攜帶版本號提交更新,版本號相同更新就會成功。
如果你再次更新并使用之前的版本號那么就會失敗。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。