Zookeeper 數據結構詳解

来源:https://www.cnblogs.com/svenaugustus/archive/2020/05/24/12951465.html
-Advertisement-
Play Games

Zookeeper https://zookeeper.apache.org/doc/current/zookeeperOver.html Zookeeper是高性能,高可用,嚴格有序的分散式協調服務,提供了統一配置(configuration),命名(naming),同步(synchronizat ...


Zookeeper

https://zookeeper.apache.org/doc/current/zookeeperOver.html

ZooKeeper is a distributed, open-source coordination service for distributed applications.
It exposes a simple set of primitives that distributed applications can build upon to implement higher level services for synchronization, configuration maintenance, and groups and naming.

It is designed to be easy to program to, and uses a data model styled after the familiar directory tree structure of file systems. 

Zookeeper是高性能,高可用,嚴格有序的分散式協調服務,提供了統一配置(configuration),命名(naming),同步(synchronization),以及分組服務(group service)。

同時,Zookeeper本身支持複製集群,實例間是兩兩連接的,維護記憶體中的數據狀態,並持久存儲中的事務日誌和快照。只要大多數伺服器可用,ZooKeeper服務將可用。
在“讀為主”的工作負載中,它特別快。ZooKeeper應用程式可在數千台電腦上運行,並且在讀取比寫入更為常見的情況下,其性能最佳,比率約為10:1。

Zookeeper 保證的特性

  • 順序一致性(Sequential Consistency):來自客戶端的更新將按照其發送順序進行執行。
  • 原子性(Atomicity):更新成功或失敗。沒有中間狀態的結果。
  • 統一視圖(Single System Image):無論客戶端連接到哪個伺服器,客戶端都將看到相同服務的數據視圖。
  • 可靠性(Reliability): 一旦數據更新被執行了,它將從那時起持續到客戶端覆蓋更新。
  • 及時性(Timeliness):確保系統的客戶視圖在特定時間範圍內是最新的。

Zookeeper的數據結構

ZooKeeper提供的名稱空間與標準文件系統的名稱空間非常相似。

file

名稱是由斜杠(/)分隔的一系列路徑元素。ZooKeeper命名空間中的每個節點都由路徑進行唯一標識。

ZooKeeper的層次命名空間

與標準文件系統不同,ZooKeeper命名空間中的每個節點都可以具有與其關聯的數據以及子節點。就像擁有一個文件系統一樣,該文件系統也允許文件成為目錄。
每一個節點都可以存儲數據,只是需要註意的是存儲的容量是有限,一般不能超過 1MiB。

Znode 類型
  • Znode的類型分為三類:

    • 持久節點(persistent node)節點會被持久
    • 臨時節點(ephemeral node),客戶端斷開連接後,ZooKeeper會自動刪除臨時節點
    • 順序節點(sequential node),每次創建順序節點時,ZooKeeper都會在路徑後面自動添加上10位的數字,從1開始,最大是2147483647 (2^32-1)
      每個順序節點都有一個單獨的計數器,並且單調遞增的,由Zookeeper的leader實例維護。
  • Znode實際上有四種形式,預設是persistent

    • PERSISTENT 持久節點: 如 create /test/a "hello" ,通過 create <path> <data>參數指定為持久節點
    • PERSISTENT_SEQUENTIAL(持久順序節點/s0000000001) ,通過 create -s <path> <data>參數指定為順序節點
    • EPHEMERAL 臨時節點,通過 create -e <path> <data>參數指定為順序節點
    • EPHEMERAL_SEQUENTIAL(臨時順序節點/s0000000001) ,通過 create -s -e <path> <data> 參數指定為臨時及順序節點

file

  • 下麵是一些實例:

(1) 創建順序節點

[zk: 127.0.0.1:2281(CONNECTED) 0] create /seq_test/ ""
Created /seq_test
[zk: 127.0.0.1:2281(CONNECTED) 1] create -s /seq_test/s "hello"
Created /seq_test/s0000000001
[zk: 127.0.0.1:2281(CONNECTED) 2] create -s /seq_test/s "hello"
Created /seq_test/s0000000002
[zk: 127.0.0.1:2281(CONNECTED) 3] ls /seq_test
[s0000000001, s0000000002]

(2) 創建臨時節點

[zk: 127.0.0.1:2281(CONNECTED) 0] create /ephe_test/ ""
Created /ephe_test
[zk: 127.0.0.1:2281(CONNECTED) 1] create -e /ephe_test/e "hello"
Created /ephe_test/e
[zk: 127.0.0.1:2281(CONNECTED) 2] ls /ephe_test
[e]

斷開重新連接

[zk: 127.0.0.1:2281(CONNECTED) 0] ls /ephe_test
[]

(3) 創建臨時順序節點

[zk: 127.0.0.1:2281(CONNECTED) 0] create /ephe_seq_test/ ""
Created /ephe_seq_test
[zk: 127.0.0.1:2281(CONNECTED) 1] create -e -s /ephe_seq_test/s "hello"
Created /ephe_seq_test/s0000000001
[zk: 127.0.0.1:2281(CONNECTED) 2] ls /ephe_seq_test
[s0000000001]
Zxid(ZooKeeper Transaction Id

file

每次的變化都會產生一個集群全局的唯一的事務id, Zxid(ZooKeeper Transaction Id),由Zookeeper的leader實例維護。
這裡的變化包括:

  • 任何的客戶端連接到Server
  • 任何的客戶端斷開與Server連接
  • 任何的Znode節點被創建create、修改set、刪除deletermr

Zxid是一個64位的數字,高32位表示紀元,從1開始,每次選舉出一個新的leader,就會遞增1;低32位是當前紀元維護的單調遞增的數字,同樣從1開始。

Znode 屬性

file

  • cZxid :創建的事務標識。
  • ctime:創建的時間戳
  • mZxid:修改的事務標識,每次修改操作(set)後都會更新mZxidmtime
  • mtime:修改的時間戳
  • pZxid:直接子節點最後更新的事務標識,子節點有變化(創建create、修改set、刪除deletermr)時,都會更新pZxid
  • cversion :直接子節點的版本號。當子節點有變化(創建create、修改set、刪除deletermr)時,cversion 的值就會增加1。
  • dataVersion :節點數據的版本號,每次對節點進行修改操作(set)後,dataVersion的值都會增加1(即使設置的是相同的數據)。
  • aclVersion :節點ACL的版本號,每次節點的ACL進行變化時,aclVersion 的值就會增加1。
  • ephemeralOwner:當前節點是臨時節點(ephemeral node )時,這個ephemeralOwner的值是客戶端持有的session id。
  • dataLength:節點存儲的數據長度,單位為 B (位元組)。
  • numChildren:直接子節點的個數。
➜ zkCli.sh -server 127.0.0.1:2281
[zk: 127.0.0.1:2281(CONNECTED) 0] get /

cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1

預設根節點 / 和 /zookeeper 是存在,因此 cZxid 是 0x0。

[zk: 127.0.0.1:2281(CONNECTED) 1] ls /
[zookeeper]
[zk: 127.0.0.1:2281(CONNECTED) 2] create /test "hello"
Created /test
[zk: 127.0.0.1:2281(CONNECTED) 3] ls /
[zookeeper, test]

當創建了一個 /test 節點後,根節點的子節點就多出來了。

[zk: 127.0.0.1:2281(CONNECTED) 4] get /test
hello
cZxid = 0x100000002
ctime = Sat May 23 15:43:10 CST 2020
mZxid = 0x100000002
mtime = Sat May 23 15:43:10 CST 2020
pZxid = 0x100000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0

為什麼cZxid 高32位是 0x1 表明瞭當前紀元為第一代,低32位是00000002 表明瞭當前紀元第2筆事務操作創建了 /test 節點。
為什麼是2呢?因為我們是通過 zkCli.sh 客戶端連接到Server的,這裡會消耗一次 Zxid。

[zk: 127.0.0.1:2281(CONNECTED) 5] set /test "hello world"
cZxid = 0x100000002
ctime = Sat May 23 15:43:10 CST 2020
mZxid = 0x100000003
mtime = Sat May 23 15:43:41 CST 2020
pZxid = 0x100000002
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 0

修改 /test 節點數據,mZxidmtimedataVersion發生了變化, dataLength 變為了( "hello world"占用了11個位元組)。

[zk: 127.0.0.1:2281(CONNECTED) 6] create /test/a ""   
Created /test/a
[zk: 127.0.0.1:2281(CONNECTED) 7] get /test              
hello world
cZxid = 0x100000002
ctime = Sat May 23 15:43:10 CST 2020
mZxid = 0x100000003
mtime = Sat May 23 15:43:41 CST 2020
pZxid = 0x100000004
cversion = 1
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 11
numChildren = 1

創建 子節點 /test/a,我們查看 /test 節點屬性,發現 pZxidcversion, numChildren 都發生了變化。

[zk: 127.0.0.1:2281(CONNECTED) 8] get /test/a

cZxid = 0x100000004
ctime = Sat May 23 15:44:12 CST 2020
mZxid = 0x100000004
mtime = Sat May 23 15:44:12 CST 2020
pZxid = 0x100000004
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 0

查看 /test/a 節點屬性,發現 cZxid 與 父節點的 pZxid 是一致的,證實了 pZxid是直接子節點最後更新的事務標識。

Znode的監視(Watch)

ZooKeeper支持 Watch。客戶端可以在znode上設置 Watch。

znode更改時,將觸發並刪除監視。觸發監視後,客戶端會收到一個數據包,說明znode已更改。

如果客戶端與其中一個ZooKeeper伺服器之間的連接斷開,則客戶端將收到本地通知。

3.6.0中的新增功能:

客戶端還可以在znode上設置永久性的遞歸監視,這些監視在觸發時不會刪除,並且會以遞歸方式觸發註冊znode以及所有子znode的更改。

支持 Watch的 客戶端命令:

  • stat path [watch]

  • ls path [watch]

  • ls2 path [watch]

  • get path [watch]

[zk: 127.0.0.1:2281(CONNECTED) 3] get /test/d watch

cZxid = 0x100000013
ctime = Sat May 23 16:47:41 CST 2020
mZxid = 0x100000013
mtime = Sat May 23 16:47:41 CST 2020
pZxid = 0x100000013
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 0

此時使用另外一個客戶端去更改 /test/d 節點的數據,我們就可以看到原來的客戶端自動收到了一個WATCHER 通知。

[zk: 127.0.0.1:2281(CONNECTED) 4] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/test/d

@SvenAugustus(https://www.flysium.xyz/)
更多請關註微信公眾號【編程不離宗】,專註於分享伺服器開發與編程相關的技術乾貨:


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天同事說新裝了一臺雲伺服器,使用ssh登錄正常,但是上面的達夢資料庫服務埠不能訪問。 用netstat anp查看埠是正常監聽的,監聽的地址也是允許任意ip訪問 並且防火牆和iptables都是關閉的 我也覺得奇怪,於是遠程登錄上去伺服器。查看了達夢的埠,看起來是正常的。 Active In ...
  • [TOC] 1.打開VMware,進入虛擬網路編輯器 2.進行如下配置 3.進入虛擬機設置 4.進行如下設置 5.進入CentOS7終端 6.重新啟動網路 ...
  • 你以為只有馬雲會灌雞湯?Linux 命令行也會! “Linux 太南了o(╥﹏╥)o”,“我累了不想奮鬥了o(︶︿︶)o”... 不知道你有沒有想過,在你快喪失鬥志的時候,Linux 還能牛逼得給你來一碗香噴噴的心靈雞湯? 和 能夠在終端隨機顯示一些激勵性的名句,可謂是兩大心靈雞湯烹飪師。 安裝 m ...
  • which 命令 功能說明:查找命令對應的程式文件的路徑。 which命令會在PATH環境變數設定的目錄里查找符合條件的可執行文件。 用法:which [options] programname [...] | 選項 | 作用 | | | | | skip alias | 忽略別名 | 示例1:查找 ...
  • [toc] 在RHEL系列中,Bash中的快捷鍵是由readline庫來提供,預設是emacs風格的鍵綁定。 使用set命令可以查看當前的模式 快捷鍵的一些說明 Control鍵:PC鍵盤上的Ctrl鍵 Meta鍵:PC鍵盤上的ALT鍵,如果你鍵盤上沒有這個鍵,可以使用ESC鍵代替 ctrl開頭的快 ...
  • Zookeeper 的集群角色 集群中的 server 分為三種角色: , , 。 其中 是配置 明確定義的,角色 在一個zookeeper集群中有且只能有一個,是通過內部的選舉機制臨時產生的。 是集群中最重要的角色。負責響應集群的所有對Zookeeper數據狀態變更的請求。它會將每個狀態更新請求進 ...
  • mysql服務啟動異常:windows無法啟動Mysql服務,位於本地電腦上的錯誤1053, 找到服務對應的mysql.exe位置,比如 G:\MySQL\MySQL Server 5.7\bin\mysql.exe 雙擊,出現缺失MSVCP120.dll 哈哈,找到了問題所在。 解決方法 微軟上 ...
  • 這幾天把項目的存儲過程從oracle遷移到了達夢8,記錄一下心得。國產資料庫做到這樣,已經算很了不起了,跟oracle相容性確實很高。 但還是有一些細節沒做好,主要是出錯提示不友好,另外一個網上的資料也很少,出問題不好定位。(達夢的錯誤碼比較簡單,就是一個負數,不像oracle是ora 錯誤碼,在百 ...
一周排行
    -Advertisement-
    Play Games
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 前言 本文介紹瞭如何使用三菱提供的MX Component插件實現對三菱PLC軟元件數據的讀寫,記錄了使用電腦模擬,模擬PLC,直至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1. PLC開發編程環境GX Works2,GX Works2下載鏈接 https:// ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • 1、jQuery介紹 jQuery是什麼 jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝 ...
  • 前言 之前的文章把js引擎(aardio封裝庫) 微軟開源的js引擎(ChakraCore))寫好了,這篇文章整點js代碼來測一下bug。測試網站:https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻譯js逆向(MD5加密,AES加密)附完整源碼 ...
  • 引言 現代的操作系統(Windows,Linux,Mac OS)等都可以同時打開多個軟體(任務),這些軟體在我們的感知上是同時運行的,例如我們可以一邊瀏覽網頁,一邊聽音樂。而CPU執行代碼同一時間只能執行一條,但即使我們的電腦是單核CPU也可以同時運行多個任務,如下圖所示,這是因為我們的 CPU 的 ...
  • 掌握使用Python進行文本英文統計的基本方法,並瞭解如何進一步優化和擴展這些方法,以應對更複雜的文本分析任務。 ...
  • 背景 Redis多數據源常見的場景: 分區數據處理:當數據量增長時,單個Redis實例可能無法處理所有的數據。通過使用多個Redis數據源,可以將數據分區存儲在不同的實例中,使得數據處理更加高效。 多租戶應用程式:對於多租戶應用程式,每個租戶可以擁有自己的Redis數據源,以確保數據隔離和安全性。 ...