Zookeeper資料結構以及實際場景操作

仲秋廿八發表於2020-04-03

1 Zookeeper特性

  • 一致性:zookeeper中的資料按照順序分批入庫,且最終一致!
  • 原子性:一次資料更新要麼成功,要麼失敗。
  • 單一檢視:全域性資料一致,每個server儲存一份相同的資料副本,client無論連線到哪個server,資料都是一致的。
  • 可靠性:每次對zk的操作狀態都會儲存到服務端,每個server儲存一份相同的資料副本。
  • 更新請求順序進行,來自同一個client的更新請求按其傳送順序依次執行。
  • 實時性,在一定時間範圍內,client能讀到最新資料。
  • 叢集中只要有半數以上節點存活,Zookeeper叢集就能正常服務(叢集選擇奇數的原因)。

2 Zookeeper資料結構

ZooKeeper資料模型的結構與Unix檔案系統很類似,整體上可以看作是一棵樹,每個節點稱做一個ZNode。每個Znode可以類似看作是一個目錄,其下可以建立子目錄。

很顯然zookeeper叢集自身維護了一套資料結構。這個儲存結構是一個樹形結構,其上的每一個節點,我們稱之為"znode",每一個znode預設能夠儲存1MB的資料,每個ZNode都可以通過其路徑唯一標識

znode.jpg

2.1 Znode有兩種型別:

短暫(ephemeral)(create -e /app1/test1 “test1” 客戶端斷開連線zk刪除ephemeral型別節點) 持久(persistent) (create -s /app1/test2 “test2” 客戶端斷開連線zk不刪除persistent型別節點)

2.2 Znode有四種形式的目錄節點(預設是persistent )

PERSISTENT 持久化 PERSISTENT_SEQUENTIAL(持久序列/test0000000019 ) EPHEMERAL 臨時 EPHEMERAL_SEQUENTIAL( 臨時序列/test0000000019 )

型別 描述
PERSISTENT 持久化節點
PERSISTENT_SEQUENTIAL 順序自動編號持久化節點,這種節點會根據當前已存在的節點數自動加1
EPHEMERAL 臨時節點, 客戶端session超時這類節點就會被自動刪除
EPHEMERAL_SEQUENTIAL 臨時自動編號節點

3 Java操作Zookeeper

3.1 Java操作zookeeper程式碼示例

  • 引入maven依賴
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.6</version>
</dependency>
複製程式碼
  • Zookeeper客戶端連線
    zookeeperClient.png
  • 建立Zookeeper節點資訊
//建立持久節點,並且允許任何伺服器可以操作
String result = zk.create("/znode1", "znode1".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("result:" + result);
//建立臨時節點
String result = zk.create("/znode2", "znode2".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("result:" + result);
複製程式碼

3.2 Watcher

在ZooKeeper中,介面類Watcher用於表示一個標準的事件處理器,其定義了事件通知相關的邏輯,包含KeeperStateEventType兩個列舉類,分別代表了通知狀態和事件型別,同時定義了事件的回撥方法:process(WatchedEvent event)。

KeeperState EventType 觸發條件 說明
None(-1) 客戶端與服務端成功建立連線
SyncConnected(0) NodeCreated(1) Watcher監聽的對應資料節點被建立
SyncConnected(0) NodeDeleted(2) Watcher監聽的對應資料節點被刪除 此時客戶端和伺服器處於連線狀態
NodeDataChanged(3) Watcher監聽的對應資料節點的資料內容發生變更
NodeChildChanged(4) Wather監聽的對應資料節點的子節點列表發生變更
Disconnected(0) None(-1) 客戶端與ZooKeeper伺服器斷開連線 此時客戶端和伺服器處於斷開連線狀態
Expired(-112) Node(-1) 會話超時 此時客戶端會話失效,通常同時也會受到SessionExpiredException異常
AuthFailed(4) None(-1) 通常有兩種情況,1:使用錯誤的schema進行許可權檢查 2:SASL許可權檢查失敗 通常同時也會收到AuthFailedException異常
  • Watcher程式碼
    ZkClientWatcher.png

3.3 使用Zookeeper實現負載均衡原理

使用Zookeeper實現負載均衡原理,伺服器端將啟動的服務註冊到,zk註冊中心上,採用臨時節點。客戶端從zk節點上獲取最新服務節點資訊,本地使用負載均衡演算法,隨機分配伺服器

  • 引入maven依賴
<dependency>
	<groupId>com.101tec</groupId>
	<artifactId>zkclient</artifactId>
	<version>0.8</version>
</dependency>
複製程式碼
  • 建立Server服務端

ZkServerScoekt.png

ServerHandler.png

ZkServerClient.png

3.4 Zookeepers實現分散式鎖

使用zookeeper建立臨時序列節點來實現分散式鎖,適用於順序執行的程式,大體思路就是建立臨時序列節點,找出最小的序列節點,獲取分散式鎖,程式執行完成之後此序列節點消失,通過watch來監控節點的變化,從剩下的節點的找到最小的序列節點,獲取分散式鎖,執行相應處理,依次類推……

ZookeeperDistrbuteLock.jpg

  • 引入Maven依賴
<dependency>
	<groupId>com.101tec</groupId>
	<artifactId>zkclient</artifactId>
	<version>0.10</version>
</dependency>
複製程式碼
  • 建立Lock介面

Lock.png

  • 建立ZookeeperAbstractLock抽象類

ZookeeperAbstractLock.png

  • ZookeeperDistrbuteLock類

ZookeeperDistrbuteLock.png

  • 使用Zookeeper鎖執行效果

zkTest.png

3.5 Zookeeper實現Master選舉

假設,在多個伺服器啟動的時候,會在zookeeper上建立相同的臨時節點,誰能夠建立成功,誰就為主伺服器,如果主伺服器當機後,繪畫連線也會失效,其他伺服器開始重新選舉

master選舉使用場景及結構 現在很多時候我們的服務需要7*24小時工作,假如一臺機器掛了,我們希望能有其它機器頂替它繼續工作。此類問題現在多采用master-salve模式,也就是常說的主從模式,正常情況下主機提供服務,備機負責監聽主機狀態,當主機異常時,可以自動切換到備機繼續提供服務(這裡有點兒類似於資料庫主庫跟備庫,備機正常情況下只監聽,不工作),這個切換過程中選出下一個主機的過程就是master選舉。 對於以上提到的場景,傳統的解決方式是採用一個備用節點,這個備用節點定期給當前主節點傳送ping包,主節點收到ping包後會向備用節點傳送應答ack,當備用節點收到應答,就認為主節點還活著,讓它繼續提供服務,否則就認為主節點掛掉了,自己將開始行使主節點職責。

相關文章