1 Zookeeper特性
- 一致性:zookeeper中的資料按照順序分批入庫,且最終一致!
- 原子性:一次資料更新要麼成功,要麼失敗。
- 單一檢視:全域性資料一致,每個server儲存一份相同的資料副本,client無論連線到哪個server,資料都是一致的。
- 可靠性:每次對zk的操作狀態都會儲存到服務端,每個server儲存一份相同的資料副本。
- 更新請求順序進行,來自同一個client的更新請求按其傳送順序依次執行。
- 實時性,在一定時間範圍內,client能讀到最新資料。
- 叢集中只要有半數以上節點存活,Zookeeper叢集就能正常服務(叢集選擇奇數的原因)。
2 Zookeeper資料結構
ZooKeeper資料模型的結構與Unix檔案系統很類似,整體上可以看作是一棵樹,每個節點稱做一個ZNode。每個Znode可以類似看作是一個目錄,其下可以建立子目錄。
很顯然zookeeper叢集自身維護了一套資料結構。這個儲存結構是一個樹形結構,其上的每一個節點,我們稱之為"znode",每一個znode預設能夠儲存1MB的資料,每個ZNode都可以通過其路徑唯一標識
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客戶端連線
- 建立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用於表示一個標準的事件處理器,其定義了事件通知相關的邏輯,包含KeeperState和EventType兩個列舉類,分別代表了通知狀態和事件型別,同時定義了事件的回撥方法: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程式碼
3.3 使用Zookeeper實現負載均衡原理
使用Zookeeper實現負載均衡原理,伺服器端將啟動的服務註冊到,zk註冊中心上,採用臨時節點。客戶端從zk節點上獲取最新服務節點資訊,本地使用負載均衡演算法,隨機分配伺服器
- 引入maven依賴
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.8</version>
</dependency>
複製程式碼
- 建立Server服務端
3.4 Zookeepers實現分散式鎖
使用zookeeper建立臨時序列節點來實現分散式鎖,適用於順序執行的程式,大體思路就是建立臨時序列節點,找出最小的序列節點,獲取分散式鎖,程式執行完成之後此序列節點消失,通過watch來監控節點的變化,從剩下的節點的找到最小的序列節點,獲取分散式鎖,執行相應處理,依次類推……
- 引入Maven依賴
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
複製程式碼
- 建立Lock介面
- 建立ZookeeperAbstractLock抽象類
- ZookeeperDistrbuteLock類
- 使用Zookeeper鎖執行效果
3.5 Zookeeper實現Master選舉
假設,在多個伺服器啟動的時候,會在zookeeper上建立相同的臨時節點,誰能夠建立成功,誰就為主伺服器,如果主伺服器當機後,繪畫連線也會失效,其他伺服器開始重新選舉
master選舉使用場景及結構 現在很多時候我們的服務需要7*24小時工作,假如一臺機器掛了,我們希望能有其它機器頂替它繼續工作。此類問題現在多采用master-salve模式,也就是常說的主從模式,正常情況下主機提供服務,備機負責監聽主機狀態,當主機異常時,可以自動切換到備機繼續提供服務(這裡有點兒類似於資料庫主庫跟備庫,備機正常情況下只監聽,不工作),這個切換過程中選出下一個主機的過程就是master選舉。 對於以上提到的場景,傳統的解決方式是採用一個備用節點,這個備用節點定期給當前主節點傳送ping包,主節點收到ping包後會向備用節點傳送應答ack,當備用節點收到應答,就認為主節點還活著,讓它繼續提供服務,否則就認為主節點掛掉了,自己將開始行使主節點職責。