### Zookeeper詳細教程
一、Zookeeper介紹
1.1 什么是zookeeper
Zookeeper是一個分布式的、高性能的、開源的分布式系統的協調(Coordination)服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的一個重要的組件。它是一個為分布式應用提供一致性服務的軟件。
1.2 zookeeper應用場景
zookeeper是一個經典的分布式數據一致性解決方案,致力於為分布式應用提供一個高性能,高可用,且具有嚴格屬性訪問控制能力的分布式協調存儲服務。
- 維護配置信息
- 分布式鎖服務
- 集群管理
- 生成分布式唯一ID
1、維護配置信息
java編程經常會遇到配置項,比如數據庫的url,schema,user和password等。通常這些配置項我們會放置在配置文件中,在將配置文件放置在服務器上當需要更改配置的時,需要去服務器上修改對應的配置信息文件。但是隨着分布式系統的興起,由於許多服務都需要使用到該配置文件,因此有必須保證該配置服務的高可用性和各台服務器上配置數據的一致性。通常會將配置文件不俗在一個集群上,然而一個集群動輒上前台服務器,此時如果在一台一台服務器逐個的修改配置文件將是非常繁瑣的一個操作。因此就需要一種服務,能夠高效快速且可靠的完成配置項的更待等操作,並能夠保證各個配置項在每一台服務器上的數據一致性。
zookeeper就可以提供這樣一種服務,其使用Zab這種一致性協議來保證一致性。現在有很多開源項目使用zookeeper來維護配置,比如hhase中,客戶端就是連接一個zookeeper,獲得必要hbase集群的配置信息然后才可以進一步操作。還有開源的消息隊列kafka中,也是用zookeeper來維護broker的信息。
2、分布式鎖服務
一個集群是一個分布式系統,有多台服務器組成。為了提高並發度和可靠性,多台服務器運行着同一種服務。當多個服務在運行時就需要協調各服務的進度,有時候需要保證當某個服務在進行某個操作時,其他的服務都不能進行該操作,即對該操作進行加鎖,如果當前機器掛掉后,並釋放fail over到其他的機器繼續執行該服務。
3、集群管理
一個集群優勢會因為各種軟硬件故障或者網絡故障,出現某種服務器掛掉而被移除集群,而某些服務器加入到集群中的情況,zookeeper會將這些服務器加入/移出的情況下通知給集群匯總的其他正常工作的服務器,以及時調用存儲和計算等任務的分配和執行等。此外zookeeper還會對故障的服務器做出診斷並嘗試修復。
4、生成分布式唯一ID
在過去的單庫單表型系統中,通常可以使用數據庫字段自帶的auto_increment屬性來自動為每條記錄生成一個唯一的ID。但是分庫分表后,就無法再依靠數據庫的auto_increatment屬性來唯一標識一條記錄了,此時我們就可以用zookeeper在分布式環境下生成全局唯一ID。做法如下:每一個生成一個新ID時,創建一個持久順序節點,創建操作返回的節點序號,及微信ID,然后把比自己節點小的刪除即可。
1.3 zookeeper的設計目標
zookeeper致力於為分布式應用提供一個高性能,高可用,具有嚴格順序訪問控制能力的分布式協調服務。
1、高性能
zookeeper將全量數據存儲在內存中,並直接服務與客戶端的所有非事務請求,尤其適合用於以讀為主的應用場景。
2、高可用
zookeeper一般以集群的范式對外提供服務,一般3-5台機器就可以組成一個可用的zookeeper集群,每一台機器都會在內存中維護當前的服務器狀態,並且每台機器之間都相互保持着通信。只要集群中超過一旦的機器都在工作,那么這個集群就能夠正常對外服務;
3、嚴格訪問數據
對於客戶端的每一個更新請求,Zookeeper都會分配一個全局唯一的遞增編號,這個編號反映了所有事物操作的先后順序。
二、Zookeeper的數據模型
2.1 zookeeper數據結構
Zookeeper數據模型的結構與Unix文件系統很類似,整體上可以看作是一顆樹,每一個節點稱做一個ZNode。每一個Znode默認能夠存儲1MB的數據,每個ZNode都可以通過其路徑唯一標識。
如何來描述一個ZNode呢?一個znode大體上分為3部分:
- 節點的數據:即znode data(節點path,節點data的關系)就像是java map中(key,value)的關系
- 節點的子節點children
- 節點的狀態stat:用來描述當前節點的創建,修改記錄,包括cZxid、ctime等。
2.2 zookeeper節點類型
zookeeper中的節點有兩種類型,一種是臨時節點和永久節點。節點類型在創建是即被確定,並且不能改變。
- 臨時節點 :該節點的生命周期依賴於創建他們的回話。一旦回話(Session)結束,臨時節點將會被自動刪除,當然可以手動的進行刪除。雖然每個臨時的ZNode都會綁定到一個客戶端回話,但他們對所有的客戶端還是可見的。另外,Zookeeper的臨時節點不允許擁有子節點。
- 持久化節點:該節點的生命周期不依賴於花花,並且只有在客戶點顯示執行刪除操作的時候,他們才能被刪除。
2.3 zookeeper 單機安裝
當前測試系統環境centos7.3
1.在centos中使用root用戶創建zookeeper用戶,用戶名:zookeeper 密碼:zookeeper
useradd zookeeper
passwd zookeeper
- zookeeper 底層依賴jdk,zookeeper用戶登錄后,根目錄下先進行jdk的安裝,jdk使用jdk-11.0.5
//解壓jdk
tar -xzvf jdk-11.0.5.tar.gz
3.配置jdk環境量
//打開/etc/profile文件
# vim /etc/profile
export JAVA_HOME=/root/apps/jdk-11.0.5
export PATH=$PATH:$JAVA_HOME/bin
//執行profile
#source /etc/profile
4.zookeeper使用zookeeper-3.4.10.tar.gz,上傳並解壓
//解壓zookeeper
tar -xzvf zookeeper-3.4.10.tar.gz
5.為zookeeper准備配置文件
//進入conf目錄
cd /root/apps/zookeeper/zookeeper-3.4.14/conf
//復制配置文件
cp zoo_sample.cfg zoo.cfg
//zookeeper根目錄下新建data目錄
mkdir data
// vi 修改配置文件中的dataDir
// 此路徑用於存儲zookeeper中數據的內存快照,及事務日志文件
dataDir=/root/apps/zookeeper/zookeeper-3.4.14/data
6.zookeeper啟動命令
[root@centos ~]# systemctl stop firewalld #關閉防火牆的命令
[root@centos ~]# zkServer.sh start #啟動
[root@centos ~]# zkServer.sh stop #關閉
[root@centos ~]# zkServer.sh status #查看運行狀態
啟動客戶端:
[root@localhost ~]# zkCli.sh //啟動客戶端
[zk: localhost:2181(CONNECTED) 0] ls / #查看根節點命令
//查看zookeeper進程是否存在
[root@centos zookeeper-3.4.14]# ps -ef | grep zookeeper
三、zookeeper常用的Shell命令
3.1 新增節點
create [-s] [-e] path data # 其中 -s 為有序節點, -e 臨時節點
1.創建持久化節點並寫入數據:
create /hadoop "123456"
2.創建持久化有序節,此時創建的節點名為指定節點名+自增序號
//創建一個持久化節點
[zk: localhost:2181(CONNECTED) 1] create /hadoop "123456"
//通過get命令獲取該節點的值
[zk: localhost:2181(CONNECTED) 2] get /hadoop
//創建一個有序的節點
[zk: localhost:2181(CONNECTED) 4] create -s /a "aa"
Created /a0000000001
//獲取路徑的值
[zk: localhost:2181(CONNECTED) 5] get /a0000000001
aa
//創建臨時節點並獲取值
[zk: localhost:2181(CONNECTED) 1] create -e /tmp "tmp"
Created /tmp
[zk: localhost:2181(CONNECTED) 2] get /tmp
tmp
3.創建臨時節點,臨時節點會在回話過期后被刪除;
[zk: localhost:2181(CONNECTED) 1] create -e /tmp "tmp"
Created /tmp
4.創建臨時有序節點,臨時節點會在會話過期后被刪除:
```xml
[zk: localhost:2181(CONNECTED) 1] create -s -e /tmp "tmp"
Created /tmp000000001
```
3.2 更新節點
//使用set命令來更新hadoop節點
[zk: localhost:2181(CONNECTED) 1] set /hadoop "345"
//根據版本號來更新節點
[zk: localhost:2181(CONNECTED) 1] set /hadoop "345" 2
也可以基於版本號來進行更改,此時類似於樂觀鎖機制,當你傳入的數據版本號(dataVersion)和當前節點的數據版本號不符合時,zookeeper會拒絕本次修改:
3.3 刪除節點
1.刪除節點的命令如下
delete path [version]
和更新節點數據一樣,也可以傳入版本號,當你傳入的數據版本號(dataVersion)和當前節點的數據版本號不符合時,zookeeper不會執行刪除操作。
//根據版本號來刪除節點
[zk: localhost:2181(CONNECTED) 1] set /hadoop "345" 2
要想刪除某個節點及其所有后代節點,可以使用遞歸刪除,命令為 rmr path。
3.4 查看節點
get path
[zk: localhost:2181(CONNECTED) 1] get /hadoop
[zk: localhost:2181(CONNECTED) 0] create /hadoop2 "hadoop"
Created /hadoop2
[zk: localhost:2181(CONNECTED) 1] get /hadoop2
hadoop
cZxid = 0xb
ctime = Thu May 14 09:06:29 CST 2020
mZxid = 0xb
mtime = Thu May 14 09:06:29 CST 2020
pZxid = 0xb
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 2]
節點各個屬性如下表。起哄一個重要的概念是Zxid(ZooKeeper Transaction Id),ZooKeeper節點的每一個更改都具唯一的Zxid,如果Zxid1小於Zxid2,則Zxid1的更改發生在Zxid2更改之前。
狀態屬性 | 節點說明 |
---|---|
cZxid | 數據節點創建時的事務ID |
ctime | 數據節點創建世的時間 |
mZxid | 數據節點最后一個更新是的事務ID |
mtime | 數據節點最后一個跟新時的時間 |
pZxid | 數據節點的子節點最后一個被修改時的事務ID |
cversion | 子節點的更改次數 |
dataVerion | 節點數據的更改次數 |
aclVersion | 節點ACL的更改次數 |
ephemeralOwner | 如果節點是臨時節點,則表示創建該節點的會話的SeeesionID;如果是持久節點,則該屬性值為0 |
dataLength | 數據內容的長度 |
numChildren | 數據節點當前的子節點個數 |
3.5 查看節點狀態
可以使用stat命令查看節點狀態,它的返回值和get命令類似,但不會返回節點數據
//使用stat命令來查看節點狀態
[zk: localhost:2181(CONNECTED) 0] stat /hadoop
cZxid = 0x4
ctime = Thu May 14 07:56:33 CST 2020
mZxid = 0x4
mtime = Thu May 14 07:56:33 CST 2020
pZxid = 0x4
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 1]
3.6 查看節點列表
查看節點列表有ls path 和ls2 path 兩個命令,后者是前者的增強。不僅可以查看指定路徑下的所有節點,還可以查看當前幾點的信息
[zk: localhost:2181(CONNECTED) 5] ls /
[a0000000001, hadoop, zookeeper, tmp, hadoop2]
[zk: localhost:2181(CONNECTED) 6] ls2 /
[a0000000001, hadoop, zookeeper, tmp, hadoop2]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0xb
cversion = 3
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 5
[zk: localhost:2181(CONNECTED) 7]
3.7 監聽器get path [watch]
使用get path [watch] 注冊的監聽器能夠在節點內容發生改變的時候,向客戶點發出通知。需要注意的是zookeeper的觸發器是一次性的(One-time trigger),觸發一次后就會立即失效。
[zk: localhost:2181(CONNECTED) 8] get /hadoop watch
123456
cZxid = 0x4
ctime = Thu May 14 07:56:33 CST 2020
mZxid = 0x4
mtime = Thu May 14 07:56:33 CST 2020
pZxid = 0x4
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 9]
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop
3.8 監聽器stat path [watch]
使用stat path [watch] 注冊的監聽器能夠在節點抓哪個台發生改變的時候,向客戶點發出通知。
[zk: localhost:2181(CONNECTED) 1] stat /hadoop watch
cZxid = 0x4
ctime = Thu May 14 07:56:33 CST 2020
mZxid = 0xf
mtime = Thu May 14 10:01:04 CST 2020
pZxid = 0x4
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 2]
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop
4.9 監聽器ls\ls2 path [watch]
使用 ls path [watch] 或者 ls2 path [watch] 注冊的監聽器能夠監聽該節點下所有子節點的增加和刪除操作。
四、zookeeper權限控制
4.1 概述
zookeeper類似於文件系統,client可以創建節點,更新節點,刪除節點,那么如何做到節點的權限的控制呢?zookeeper的access control list 訪問控制列表可以自耦到這一點。
acl權限控制,使用scheme:id:permission來表示,主要涵蓋3個方面:
-
權限模式(scheme):授權的策略
-
授權對象(id):授權的對象
-
權限(permission):授予的權限
其特性如下:
-
zookeeper的權限控制是基於每個znode節點的,需要對每個節點設置權限
-
每個znode支持設置多種權限控制方案和多個權限
-
子節點不會繼承父節點的權限,客戶點無權訪問某個節點,但可能可以訪問他的子節點
setAcl /test2 ip:192.168.60.130:rewda //將節點權限設置為Ip:192.168.60.130的客戶端可以對節點進行增、刪、該、查、權限管理
4.2 權限模式
采用何種方式授權
方案 | 描述 |
---|---|
world | 只有一個用戶:anyone,代表登錄zooleeper所有人(默認) |
ip | 對客戶端使用ip地址認證 |
auth | 使用已添加認證的用戶認證 |
digest | 使用“用戶名:密碼”方式認證 |
4.3 授權的對象
給誰授權
授權對象ID是指,權限賦予的實體例如:ip地址或用戶。
4.4 授予的權限
授予什么權限
create、delete、read、writer、admin也就是增、刪、改、查、管理權限,這5中權限簡寫為cdrwa、注意:這5中權限中,delete是指對子節點的刪除權限,其他4種權限值對自身節點的權限操作。
權限 | ACL簡寫 | 描述 |
---|---|---|
create | c | 可以創建子節點 |
delete | d | 可以刪除子節點(僅下一級節點) |
read | r | 可以讀取節點數據及顯示子節點列表 |
write | w | 可以設置節點數據 |
admin | a | 可以設置節點訪問控制列表權限 |
4.5 授權的相關命令
命令 | 使用方式 | 描述 |
---|---|---|
getAcl | getAcl
|
讀取ACL權限 |
setAcl | setAcl
|
設置ACL權限 |
addauth | addauth
|
添加認證用戶 |
4.6 案例
-
world授權模式:
命令
setAcl <path> world:anyone:<acl> setAcl /hadoop world:anyone:cdrwa
案例
[zk: localhost:2181(CONNECTED) 2] getAcl /hadoop 'world,'anyone #world方式對所有用戶進行授權 : cdrwa #增、刪、改、查、管理 [zk: localhost:2181(CONNECTED) 3]
-
IP 授權模式
命令
#需要兩台機器來進行連接 192.168.60.129 192.168.60.130 #使用 192.168.60.129 登錄zookeeper zkCli.sh -server 192.168.60.130 #使用本機 192.168.60.130 zookeeper zkCli.sh -server 192.168.60.130
-
Auth授權模式
命令
addauth digest <user>:<password> #添加認證用戶 setAcl <path>auth:<user>:<acl>
案例
[zk: localhost:2181(CONNECTED) 0] create /hadoop3 "hadoop3"
Created /hadoop3
[zk: localhost:2181(CONNECTED) 1] getAcl /hadoop3
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 2] addauth digest tyx:123
[zk: localhost:2181(CONNECTED) 3] setAcl /hadoop3 auth:tyx:cdrwa
cZxid = 0x16
ctime = Thu May 14 20:29:34 CST 2020
mZxid = 0x16
mtime = Thu May 14 20:29:34 CST 2020
pZxid = 0x16
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 7
numChildren = 0
[zk: localhost:2181(CONNECTED) 7] getAcl /hadoop3
'digest,'tyx:nSk0WYb+XoISHNhIQiQ1BGsZHjE=
: cdrwa
[zk: localhost:2181(CONNECTED) 8]
-
Digest 授權模式
命令
setAcl <path> digest:<user>:<password>:<acl>
這里的密碼是經過SHA1及BASE64處理的密文,在SHEEL中可以通過命令計算:
echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64
先來計算一個密文
echo -n tyx:123 | openssl dgst -binary -sha1 | openssl base64 #得到的密文 [root@centos zookeeper-3.4.14]# echo -n tyx:123 | openssl dgst -binary -sha1 | openssl base64 nSk0WYb+XoISHNhIQiQ1BGsZHjE=
案例:
[zk: localhost:2181(CONNECTED) 8] create /hadoop4 "hadoop4" Created /hadoop4 [zk: localhost:2181(CONNECTED) 10] getAcl /hadoop4 'world,'anyone : cdrwa //使用digest進行授權 [zk: localhost:2181(CONNECTED) 11] setAcl /hadoop4 digest:tyx:nSk0WYb+XoISHNhIQiQ1BGsZHjE=:cdrwa //該節點的權限 [zk: localhost:2181(CONNECTED) 13] getAcl /hadoop4 'digest,'tyx:nSk0WYb+XoISHNhIQiQ1BGsZHjE= : cdrwa //沒有權限 [zk: localhost:2181(CONNECTED) 0] get /hadoop4 Authentication is not valid : /hadoop4 //添加授權用戶 [zk: localhost:2181(CONNECTED) 1] addauth digest tyx:123 [zk: localhost:2181(CONNECTED) 2] get /hadoop4 hadoop4 cZxid = 0x19 ctime = Thu May 14 21:12:46 CST 2020 mZxid = 0x19 mtime = Thu May 14 21:12:46 CST 2020 pZxid = 0x19 cversion = 0 dataVersion = 0 aclVersion = 1 ephemeralOwner = 0x0 dataLength = 7 numChildren = 0
-
多種密室授權:
同一個節點可以同時使用多種模式授權
[zk: localhost:2181(CONNECTED) 8] create /hadoop4 "hadoop4" Created /hadoop4 //添加認證用戶 [zk: localhost:2181(CONNECTED) 8] addauth digest itcast:123456 [zk: localhost:2181(CONNECTED) 8] setAcl /hadoop4 ip:192.168.60.129:cdrwa,auth:tyx:123:cdrwa,digest:tyx:nSk0WYb+XoISHNhIQiQ1BGsZHjE=:cdrwa
4.7 acl 超級管理員
zookeeper的權限管理模式有一種叫做super,該模式提供一個超管,可以方阿斌的訪問任何權限的節點
假設這個超管是:super:admin,需要先為超管生成密碼的密文
echo -n super:admin | openssl dgst -binary -sha1 | openssl base64
那么打開zookeeper目錄下的/bin/zkServer.sh 服務器腳本,找到如下一行:
之后啟動zookeeper,輸入如下的命令添加權限
addauth digest super:admin #添加認證用戶
五、zookeeper javaAPI
znode是zookeeper集合的核心組件,zookeeper API提供了一小組方法使用zookeeper集合來操作znode所有的細節。
客戶端用該遵循以下步驟,與zookeeper服務器進行清洗和干凈的交互。
- 連接到zookeeper服務器。zookeeper服務器為客戶端分配回話ID。
- 定期向服務器發送心跳。否則,zookeeper服務器將過期回話ID,客戶端需要重新連接。
- 只要回話ID處於活動狀態,就可以獲取/設置znode。
- 所有任務完成后,斷開與zookeeper服務器的連接。如果客戶端長時間不活動,則zookeeper服務器將自動斷開客戶端。
5.1 連接到zookeeper
Zookeeper(String connectionString,int sessionTimeout,Watcher watcher)
- connectionString -zookeeper 主機
- sessionTimeout - 回話超時(一毫秒為單位)
- watcher -實現“監視器”對象。zookeeper集合通過監視器對象返回連接狀態。
package com.example.springcloud.controller;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
* @author papi
* @data 2020/5/1
*/
public class ZookeeperTest {
public static void main(String[] args) {
try {
CountDownLatch countDownLatch = new CountDownLatch(1);
//arg1:服務器和端口號
//arg2: 客戶端和服務器之間的會話超時時間
//arg3: 監視器對象
ZooKeeper zooKeeper = new ZooKeeper("192.168.90.108:2181", 5000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
System.out.println("連接成功");
//通知主線不要去等待了
countDownLatch.countDown();
}
}
});
//主線程阻塞等待連接對象
countDownLatch.await();
//獲取zookeeper的session會話編號
System.out.println(zooKeeper.getSessionId());
zooKeeper.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
5.2 新增節點
//同步方式
create(String path, byte[] data, List<Acl> acl, CreateMode createMode)
//異步方式
create(String path, byte[] data, List<Acl> acl, CreateMode createMode, AsyncCallback.StringCallback callBack,Object ctx)
- path -znode路徑。例如,/node1 /node1/node11
- data -要存儲的指定znode路徑中的數據
- acl - 要創建的節點的訪問控制列表。zookeeper API提供了一個靜態接口ZooDefs.Ids 來獲取一些基本的acl列表。例如,Zoodefs.Ids.OPEN_ACL_USERAFE 返回發開znode的acl列表。
- createMode -節點的類型,這是一個枚舉。
- callBack -異步回調接口
package com.example.springcloud.controller;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
/**
* @author papi
* @data 2020/5/15
*/
public class ZookeeperTest {
public static void main(String[] args) {
try {
CountDownLatch countDownLatch = new CountDownLatch(1);
//arg1:服務器和端口號
//arg2: 客戶端和服務器之間的會話超時時間
//arg3: 監視器對象
ZooKeeper zooKeeper = new ZooKeeper("192.168.90.108:2181", 5000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
System.out.println("連接成功");
//通知主線不要去等待了
countDownLatch.countDown();
}
}
});
//主線程阻塞等待連接對象
countDownLatch.await();
//獲取zookeeper的session會話編號
System.out.println(zooKeeper.getSessionId());
zooKeeper.create("/hadoop7","hadoop7".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
//ZooDefs.Ids.READ_ACL_UNSAFE world:anyone:r
zooKeeper.create("/hadoop8", "hadoop8".getBytes(), ZooDefs.Ids.READ_ACL_UNSAFE, CreateMode.PERSISTENT );
//world 模式
//權限列表
List<ACL> list = new ArrayList<>();
Id id = new Id();
id.setScheme("world");
id.setId("anyone");
list.add(new ACL(ZooDefs.Perms.READ, id));
list.add(new ACL(ZooDefs.Perms.WRITE, id));
zooKeeper.create("/hadoop9", "hadoop9".getBytes(), list, CreateMode.PERSISTENT );
//IP授權模式
List<ACL> acls = new ArrayList<>();
//授權模式和授權對象
Id id1 = new Id("ip", "192.168.60.130");
acls.add(new ACL(ZooDefs.Perms.ALL, id1));
zooKeeper.create("/hadoop10", "hadoop10".getBytes(), acls, CreateMode.PERSISTENT);
//使用auth模式進行授權
zooKeeper.addAuthInfo("digest","tyx:123".getBytes());
zooKeeper.create("/hadoop11", "hadoop11".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.PERSISTENT);
//使用auth模式進行授權,只讀的模式
zooKeeper.addAuthInfo("digest","tyx:123".getBytes());
List<ACL> acls2 = new ArrayList<>();
Id id2 = new Id("auth", "tyx");
acls.add(new ACL(ZooDefs.Perms.READ, id1));
zooKeeper.create("/hadoop12", "hadoop12".getBytes(), acls2,CreateMode.PERSISTENT);
//使用digest模式進行授權
List<ACL> acls3 = new ArrayList<>();
Id id3 = new Id("digest", "tyx:adkalfjasncasaKJHG=");
acls.add(new ACL(ZooDefs.Perms.ALL, id3));
zooKeeper.create("/hadoop13", "hadoop13".getBytes(), acls3,CreateMode.PERSISTENT);
//持久化有序節點
zooKeeper.create("/hadoop14", "hadoop14".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.PERSISTENT_SEQUENTIAL);
//臨時節點
zooKeeper.create("/hadoop15", "hadoop15".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.EPHEMERAL);
//臨時順序節點
zooKeeper.create("/hadoop16", "hadoop16".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL,CreateMode.EPHEMERAL_SEQUENTIAL);
//異步創建節點
zooKeeper.create("/hadoop16", "hadoop16".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT, new AsyncCallback.StringCallback() {
@Override
public void processResult(int i, String s, Object o, String s1) {
//0代表創建成功
System.out.println(i);
//節點的路徑
System.out.println(s);
//節點的路徑
System.out.println(o);
//上下文參數
System.out.println(s1);
}
},"I am context");
zooKeeper.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
5.3 更新節點
//同步方式
setData(String path,byte[] data, int version)
//異步方式
setData(String path, byte[] data, int version, AsyncCallback.StatCallback callBack, Object ctx)
- path -znode路徑
- data -要存儲在指定znode路徑中的數據。
- version -znode的當前版本號。每當數據更改時,Zookeeper會更新znode的版本號。
- callBack -異步回調接口
- ctx 傳遞上下文參數
5.4 刪除節點
//同步方式
delete(String path, int version)
//異步方式
delete(String path, int version, AsyncCallback.VoidCallback callBack, Object ctx)
- path -znode路徑
- version -znode的當前版本
- callBack -異步回調接口
- ctx -傳遞上下文參數
案例
//arg1:刪除節點的節點路徑
//arg2:數據版本信息 -1代表刪除節點時不考慮節點版本信息
zooKeeper.delete("/delete/node1", -1);
delete(String path, int version, AsyncCallback.VoidCallback callBack, Object ctx)
5.5 查看節點
//同步方式
getData(String path, boolean b, Stat stat)
//異步方式
getData(String path, boolean b, AsyncCallback.DataCallback callBack, Object ctx)
- path -znode路徑
- b -是否使用連接對象中注冊的監視器。
- stat -返回znode的元數據。
- callBack -異步回調接口
- ctx -傳遞上下文參數
//異步方式獲取
5.6 查看子節點
//同步方式
getChildren(String path, boolean b)
//異步方式
getChildren(String path, boolean b, AsyncCallback.ChildrenCallback callBack, Object ctx)
- path -Znode路徑。
- b -是使用連接對象中注冊的監視器。
- callBack -異步回調接口。
- ctx -傳遞上下文參數。
//同步方式
List<String> list = zookeeper.getChildren("/get",false);
for(String str : list){
System.out.println(str);
}
//異步方式
zookeeper.getChildren("/get", false, new AsyncCallback.ChildrenCallback(){
@Override
public void processResult(int rc, String path,Object ctx, List<String> children){
//0代表讀取成功
System.out.println(rc);
//子節點路徑
System.out.println(path);
//上下文參數對象
System.out.println(ctx);
//子節點信息
for(String str : children){
System.out.println(str);
}
}
},"I am Context")
Thread.sleep(1000);
6.7 檢查節點是否存在
//同步方法
exists(String path, boolean b);
//異步方法
exists(String path, boolean b, AsyncCallback.StatCallBack, Object ctx)
- path -znode路徑
- b -是否使用連接對象中注冊的監視器
- callBack -異步回調接口
- ctx -上下文參數
六、zookeeper事件監聽機制
6.1 watcher概念
zookeeper提供了數據的發布/訂閱功能,對個訂閱者可同時監聽某一特定主題對象,當該主題對象的自身狀態發生變化時(例如節點內容改變,節點下的子節點列表改變等),會實時,主動通知所有訂閱者;
zookeeper采用了watcher機制實現數據的發布/訂閱功能。該機制在被訂閱對象發生變化時會異步通知客戶端,因此客戶端不必在Watcher注冊后輪詢阻塞,從而減輕了客戶點壓力。
watcher機制實際上與觀察者密室類似,也可以看作是一種觀察者密室在分布式場景下的實現方式。
6.2 wathcer架構
Watcher實現由三個部分組成:
- Zookeeper服務端
- Zookeeper客戶端
- 客戶端的ZKWatchManager對象
客戶端首先將Watcher注冊到服務端,同時將Watcher對象保存到客戶端的Watch管理器中。當Zookeeper服務端監聽的數據狀態發生變化時,服務端會主動同時客戶端,接着客戶端的Watch管理器會觸發相關Watcher來回調相應處理邏輯,從而完成整體的數據發布/訂閱流程。
6.3 wahcher特性
特性 | 說明 |
---|---|
一次性 | wathcer是一次性的,一旦被觸發就會移除,再次使用時需要重新注冊 |
客戶端順序回調 | watcher回調是順序串行化執行的,只有回調后客戶端才能看到最新的數據狀態。一個watcher回調邏輯不用太多,以免影響別的watcher執行 |
輕量級 | wathcerEvent是最小的通信單元,結構上只包含通知狀態,事件類型和節點路徑,並不會告訴數據節點變化前后的具體內容; |
時效性 | watcher只有在當前session徹底失效時才會無效,若session有效期內快速重連成功。則wacher依然存在,然可接收到通知; |
6.4 watcher接口設計
- Wacher通知狀態
KeeperState是客戶端與服務daunt連接狀態發生變化時對應的通知類型。路徑為org.apache.zookeeper.Watcher.Event.KeeperState,是一個枚舉類,其枚舉屬性如下:
枚舉屬性 | 說明 |
---|---|
SyncConnected | 客戶端與服務器正常連接時 |
Disconnected | 客戶端與服務器斷開連接時 |
Expired | 回話session失效時 |
AuthFailed | 身份認證失敗時 |
-
Watcher事件類型(EventType)
EventType是數據節點(znode)發生變化時對應的通知類型。EventType變化時KeeperState永遠處於SyncConnected通知狀態下;當KeeperState發生變化時,EventType永遠為None。其路徑為org.apache.zookeeper.Watcher.Event.EventType,是一個枚舉類,枚舉類屬性如下:
枚舉屬性 | 說明 |
---|---|
None | 無 |
NodeCreated | Watcher監聽的數據節點被創建時 |
NodeDeleted | Watcher監聽的數據節點被刪除時 |
NodeDataChanged | Watcher監聽的數據節點內容發生變更時(無論內容數據是否變化) |
NodeChildrenChanged | Watcher監聽的數據節點的子節點列表發生變更時 |
6.5 捕獲相應的事件
上面講到的zookeeper客戶端連接的狀態和zookeeper對znode節點監聽的事件類型,下面我們來將如何建立zookeeper的watcher監聽。在zookeeper中采用zk.getChildren(path,watch)、zk.exists(path,watch),zk.getData(path,watcher,stat)這樣的方式為某個znode注冊監聽。
下表以node-x節點為例,說明調用的注冊方法和監聽事件間的關系:
注冊方式 | Created | ChildrenChanged | Changed | Deleted |
---|---|---|---|---|
zk.exists("/node-x",watcher) | 可監控 | 可監控 | 可監控 | |
zk.getData("/node-x",watcher) | 可監控 | 可監控 | ||
zk.getChildren("/node-x",watcher) | 可監控 | 可監控 |
6.5 注冊watcher的方法
客戶端與服務器的連接狀態
KeeperState : 通知狀態
SyncConnected:客戶端與服務器正常連接時
Disconnected:客戶端與服務器斷開連接時
Expired:回話session失效時
AuthFailed:身份認證失敗時
事件類型為:None
6.6 查看節點
//使用連接對象的監聽器
getData(String path, boolean b, Stat stat)
//滴定儀監視器
getData(String path, boolean b, Stat stat)
//NodeDeleted:節點刪除
//NodeDataChanged:節點內容發生變化
- path -znode路徑。
- b -是否使用連接對象中注冊的監聽器。
- w -監視器對象。
- stat - 返回znode的元數據
七、配置中心案例
工作中有這樣一個場景:數據庫用戶名和密碼信息放在一個配置文件中,應用讀取該配置文件,配置文件信息放入緩存。
若數據庫的用戶名和密碼改變時候,還需要重新加載緩存,比較麻煩,通過Zookeeper可以輕松完成,當數據庫發生變化時自動完成緩存同步。
設計思路:
- 連接zookeeper服務器
- 讀取zookeeper中的配置信息,注冊watcher監聽器,存入本地變量
- 當zookeeper中的配置信息發生變化時,通過watcher的回調方法捕獲數據變化事件。
- 重新獲取配置信息。
八、生成分布式唯一ID
在過去的單庫單表型系統中,通常可以使用數據庫字段自帶的auto_increment屬性來自動為每條記錄生成一個唯一的ID。但是分庫分表后,就無法再依靠數據庫的auto_increment屬性唯一標識一條記錄了。此時我們就可以用zookeeper在分布式環境下生成全局唯一ID。
設計思路:
- 連接zookeeper服務器
- 指定路徑下生成臨時有序節點
- 取序號及為分布式環境下的唯一ID
九、分布式鎖
分布式鎖有多重實現方式,比如通過數據庫,redis都可以實現。作為分布式協同工具Zookeeper,當然也有者標准的實現方式。下面介紹在zookeeper中如何實現排它鎖。
設計思路:
1、每個客戶端往/Locks下創建臨時有序節點/Locks/Lock_,創建成功后/Locks下面會有每個客戶端對應的節點。如/Locks/Lock_0000001
2、客戶端取得/Locks下子節點,並進行排序,判斷排在最前面的是否為自己,如果自己的鎖節點在第一位,代表獲取鎖成功。
3、如果自己的鎖節點不在第一位,則監聽自己前一位的鎖節點。如果自己鎖節點Lock_000002,那么則監聽Lock_0000001
4、當前一位鎖節點(Lock_000000001)對應的客戶端執行完成,釋放了鎖,將會觸發監聽客戶端(Lock_000002)的邏輯
5、監聽客戶端重新執行第2步邏輯,判斷自己是否獲得了鎖;
十、zookeeper集群搭建
單機環境下,jdk、zookeeper安裝完畢,基於一台虛擬機,進行zookeeper偽集群搭建,zookeeper集群中包含3個節點,節點對外提供服務端口號分別為2181,2182,2183
10.1配置zookeeper服務器文件
1、基於zookeeper-3.4.14復制三分zookeeper安裝好的服務器文件,目錄名稱分別為zookeeper2181、zookeeper2182、zookeeper2183
cp -r zookeeper-3.4.14 zookeeper2181
cp -r zookeeper-3.4.14 zookeeper2182
cp -r zookeeper-3.4.14 zookeeper2183
2.修改zookeeper2181服務器對應配置文件
#服務器對應端口號
clientPort=2181
#數據快照文件所在路徑
dataDir=/home/zookeeper/zookeeper2181/data
#集群配置信息
#server.A=B:C:D
#A:是一個數字,表示這個是服務器的編號
#B:是這個服務器的ip地址
#C:Zookeeper服務器之間的通信端口號
#D:Leader選舉的端口
server.1=192.168.60.130:2287:3387
server.1=192.168.60.130:2288:3388
server.1=192.168.60.130:2289:3389
- 在上一步dataDir指定的目錄下,創建myid文件,然后在該文件添加上一步server配置對應A數字。
#zookeeper2181對應的數字為1
#/home/zookeeper/zookeeper2181/data目錄下執行命令
echo "1" > myid
4.zookeeper2182 、zookeeper2183參照2,3不找進行相應配置
5.分別啟動三台服務器,檢驗集群狀態
登錄命令:
./zkCli.sh -server 192.168.60.130:2181
./zkCli.sh -server 192.168.60.130:2182
./zkCli.sh -server 192.168.60.130:2183
10.2 一致性協議:zab協議
zab協議的全稱是Zookeeper Atomic Broadcast (zookeeper原子廣播)。zookeeper是通過zab協議來保證分布式事務的最終一致性
基於zab協議,zookeeper集群中的角色主要有一下三類,如下表所示:
角色 | 描述 |
---|---|
領導者(leader) | 領導者負責進行投票的發起和決議,更新系統狀態 |
學習者(Learner) | Follower用於接受客戶請求並向客戶端返回結果,在選主過程中參與投票 |
ObServer可以接受客戶端連接,將寫請求轉發給leader節點。但是ObServer不參加投票過程,只同步leader的狀態。ObServer的目的是為了擴展系統,提高讀取速度 | |
客戶端(Client) | 請求發起方。 |
zab廣播模式工作原理,通過類似兩階段提交協議的方式解決數據一致性:
- leader從客戶端收到一個寫請求
- leader生成一個新的事務並未這個事務生成一個唯一的ZXID
- leader將這個事務提議(propose)發送給所有的follows節點
- follower節點將收到的事務請求加入到歷史隊列(history queue)中,並發送ack給leader
- 當leader收到大多數follower(半數以上節點)的ack消息,leader會發送commit請求
- 當follower收到commit請求時,從歷史隊列中將事務請求commit
10.3 zookeeper的leader選舉
1、服務器狀態
looking:尋找leader狀態。當服務器處於該狀態時,它會認為當前集群中沒有leader,因此需要進入leader選舉狀態。
leading:領導者狀態。表明當前服務器角色是leader。
**following**:跟隨者狀態。表明當前服務器角色是follower。
observing:觀察者狀態。表明當前服務器角色是observer。
2、服務器啟動時期的leader選舉
在集群初始化階段,當有一台服務器server啟動時,其單獨無法進行完成leader選舉,當第二太服務器server2啟動時,此時兩台機器可以相互通信,每台機器都視圖zhaodaoleader。於是進入leader選舉過程。選舉過程如下:
- 每個server發出一個投票。由於是初始情況,server1和server2都會將自己作為leader服務器進行投票,沒投票會包含所推舉的服務器的myid和zxid,使用(myid,zxid(事務ID))來表示,此時server1的投票為(1,0),server2的投票為(2,0),然后各自將這個投票發給集群中其他機器。
- 集群中的每一台服務器接受來自集群中各個服務器的投票。
- 處理投票。針對每一個投票,服務器都需要將別人的投票和自己的投票進行pk,pk規則如下
- 優先檢查zxid(事務的編號)。zxid比較大的服務器優先為leader。
- 如果zxid相同,那么就比較myid(服務器的編號)。myid比較大的服務器作為leader服務器。
對於Server1而言,它的投票是(1,0),接受Server2的投票為(2,0),首先會比較兩者的zxid,均為0,在比較myid,此時server2的myid最大,於是更新自己的投票為(2,0),然后重新投票,對於server2而言,其無須更新自己的投票,只是再次向集群中所有機器發出上一次的投票信息即可。
4. 統計投票。每次投票后,服務器都會統計投票信息,判斷是否已經有過半機器接受到相同的投票信息,對於server1、server2而言,都統計出集群中已經有兩台機器接受了(2,0)的投票信息,此時便認為已經選出了leader。
5. 改變服務狀態。一旦確定了leader,每個服務器就會更新自己的狀態,如果是follower,那么久變更為following,如果是leader,就變更為leading。
10.4 服務器運行時期的Leader選舉【zxid:事務ID】
在zookeeper運行期間,leader與非leader服務器各司其職,即便當有非leader服務器宕機或新加入,此時也不會影響leader,但是一旦leader服務器掛了,那么這個集群將暫停對外服務,進入新一輪leader選舉,其過程和啟動時期的Leader選舉過程基本一致。
假設正在運行的server1、server2、server3三台服務器,當前leader是server2,若某一時刻leader掛了、此時開始Leader選舉。選舉過程如下:
- 變更狀態。leader掛后,剩余的服務器都會將自己的服務狀態變更為looking,然后開始進入leader選舉過程。
- 每個server會發出一個投票。在運行期間,每個服務器上的zxid可能不同,此時嘉定server1的ZXID為122,server3的zxid為122,在第一輪投票中,server1和server3都會投自己、產生投票(1,122),(3,122),然后各自將投票發送給集群中的所有機器。
- 接受來自各個服務器的投票。與啟動時過程相同。
- 處理投票。與啟動時過程相同,此時,server3將會成為leader。
- 統計投票。與啟動時過程相同。
- 改變服務器的狀態。與啟動時過程相同。
10.5 observer角色及其配置
observer角色特點:
-
不參與集群的leader選舉
-
不參與集群中寫數據時的ack反饋
為了使用observer角色,在任何想變成observer角色的配置文件中加入如下配置:
peerType=observer
並在所有的server的配置文件中,配置成observer模式的server的哪行配置追加:observer,例如:
server.3=192.168.60.130:2289:3389:observer
10.6 zookeeperAPI連接集群
Zookeeper(String connectionString, int sessionTimeout, Watcher watcher)
- **connectionString ** -zooKeeper集合主機
- sessionTimeout - 回話超時(以毫秒為單位)。
- watcher - 實現“監視器”界面的對象。Zookeeper集合通過監視器對象返回連接狀態。
十一、zookeeper開源客戶端curator介紹
- zookeeper開源客戶端curator介紹
- zookeeper四字監控命令
- zookeeper圖形化的客戶端工具(Zoolnspector)
- taokeeper監控工具的使用
11.1 curator簡介
curator是Netflix公司開源的一個zookeeper客戶端,后捐贈給apache,curator框架在走哦科普日原生API接口上進行了包裝,解決了很多zookeeper客戶端非底層的細節開發。提供了zookeeper各種應用場景(比如:分布式鎖服務,集群領導選舉,共享計數器,緩存機制,分布式隊列等)的抽象封裝,實現了Fluent風格的API接口,是最好用,最流行的zookeeper的客戶端。
原生zookeeperAPI的不足:
-
連接對象異步創建,需要開發人員自行編碼等待。
-
連接沒有自動重連超時機制
-
watcher一次注冊生效一次
-
不支持遞歸創建樹形節點
curator特點:
-
解決session會話超時重連
-
watche反復注冊
-
簡化開發api
-
遵循Fluent風格的API
-
提供了分布式鎖服務,共享計數器,緩存機制等機制
11.2 zookeeoer 四字監控命令
zookeeper支持某些特定的四字命令與其他的交互。他們大多數是查詢命令,用來獲取zookeeper服務的當前狀態及相關的信息。用戶在客戶點可以通過telnet或nc向zookeeper提交相應的命令。走哦可額偶爾常用的四字命令見下表:
命令 | 描述 |
---|---|
conf | 輸出相關服務的配置的詳細信息。比如端口,zk數據及日志配置路徑,最大連接數,session超時時間,serverid等。 |
cons | 列出所有連接到台服務器的客戶端連接/回話的詳細信息。包括“接受/發送”的包數量、session id。操作延遲,最后的操作執行等信息。 |
crst | 重置當前這台服務器所有連接/回話的統計信息 |
envi | 輸出關於服務器的環境詳細信息 |
ruok | 測試服務器的詳細信息:接受/發送包數量、連接數、模式(leader/follower)、節點總數、延遲、所有客戶端的列表。 |
srst | 重置server狀態 |
wchs | 累出服務器watches的簡潔信息:連接總數、watching節點總數和watches總數 |
wchc | 通過session分組,累出watch的所有節點,它的輸出是一個與watch相關的回話的節點列表 |
mntr | 雷虎集群的健康狀態。包括“接受/發送”的包數量,操作延遲,當前服務模式(leader/follower)、節點總數,watch總數,臨時節點總數 |
11.3 conf 命令
conf:輸出相關服務配置的詳細信息
shell終端輸入:echo conf | nc localhost 2181
屬性 | 含義 |
---|---|
clientPort | 客戶端端口號 |
dataDir | 數據快照文件目錄 默認情況下100000次事務操作生成一次快照 |
dataLogDir | 事務日志文件目錄,生產環境中放在獨立的磁盤上 |
tickTime | 服務器之間或客戶端與服務器至今維持心跳的時間間隔(以毫秒為單位) |
maxClientCnxns | 最大連接數 |
minSessionTimeout | 最小session超時minSessionTimeout=tickTime*2 |
maxSessionTimeout | 最大session超時maxSessionTimeout=tickTime*20 |
serverId | 服務器編號 |
initLimit | 集群中的follower服務器(F)與leader服務器(L)之間初始連接時能容忍的最多心跳數 |
syncLimit | 集群中的follower服務器(F)與leader服務器(L)之間請求和答應之間能容忍的最多心跳數 |
electionAlg | 0:基於UDP的LeaderElection 1:基於UDP的FastLeaderElection 2:基於UDP和認證的FastLeaderElection 3:基於TCP的FastLeaderElection 在3.4.10版本中,默認值為3,另外的三種算法已經被棄用了,並且有計划在之后的版本中將它們徹底鏟除而不再支持。 |
electionPort | 選舉端口 |
quorumPort | 數據通信端口 |
peerType | 是否為觀察者 1 為觀察者 |
11.4 cons命令
cons:列出所有連接到這台服務器的客戶端連接/回話的詳細信息
echo cons | nc localhost 2181
屬性 | 含義 |
---|---|
ip | IP地址 |
port | 端口號 |
queued | 等待被處理的請求數,請求緩存在隊列中 |
received | 收到的包數 |
sent | 發送的包數 |
sid | 回話id |
lop | 最后的操作GETD-讀取數據DELE-刪除CREA-創建數據 |
est | 連接時間戳 |
to | 超時時間 |
lcxid | 當前回話的操作id |
lzxid | 最大事務id |
llat | 最后/最新 延時 |
minlat | 最小延時 |
maxlat | 最大延時 |
avglat | 平均延時 |
11.5 crst命令
crst:重置當前這台服務器所有連接/繪畫的統計信息
shell終端輸入:echo crest | nc localhost 2181
11.6 dump命令
dump:列出未經處理的回話和臨時節點
shell終端輸入:echo dump | nc loalhost 21
屬性 | 含義 |
---|---|
session id | znode path(1對多,處於隊列中排隊的session和臨時節點) |
11.7 eniv命令
envi:輸出關於服務器的環境詳細信息
shell終端輸入:echo envi |nc localhost 2181
屬性 | 含義 |
---|---|
zookeeper.version | 版本 |
host.name | host信息 |
java.version | java版本 |
java.vendor | 供應商 |
java.home | 運行環境所在目錄 |
java.class.path | classpath |
java.library.path | 第三方庫指定非java類包的位置(如:dll,so) |
java.io.tmpdir | 默認的臨時文件路徑 |
java.compiler | JIL編譯器的名稱 |
os.name | Linux |
os.arch | amd64 |
os.version | XXXXXXX |
user.name | zookeeper |
user.home | /home/zookeeper |
user.dir | /home/zookeeper/zookeeper2181/bin |
11.8 ruok命令
ruok:測試服務是否處於正確運行狀態
echo ruok | nv 192.168.60.120 2181
11.9 stat命令
stat:輸出服務器的詳細信息與srvr相似,但是多了每個連接的回話信息
shell終端輸入:echo stat | nc localhost 2181
屬性 | 含義 |
---|---|
Zookeeper version | 版本 |
Latency min/avg/max | 延時 |
Received | 收包 |
Sent | 發包 |
Connections | 連接數 |
OutStanding | 堆積數 |
Zxid | 最大事務id |
Mode | 服務器角色 |
Node count | 節點數 |
11.10 srst命令
srst:重置server狀態
shell終端輸入:schoolsrst | nc localhost 2181
11.11 wchs命令
wchs:累出服務器watches的簡潔信息
shell終端輸入:echo wchs | nc localhost 2181
屬性 | 含義 |
---|---|
connectsions | 連接數 |
watch-paths | watch節點數 |
watchers | watcher數量 |
11.12 wchc命令
wchc:通過session分組,累出watch的所有節點,它的輸出的是一個與watch相關的回話的節點列表問題:
問題:
wchc is not executed because it is not in the whiltelist
解決方法:
#修改啟動指令 zkServer.sh
#注意找到這個信息
else
echo "JMX disabled by user request" > & 2
ZOOMAIN = "org.apache.zookeeper.server.quorum.QuorumPeerMain"
fi
# 添加如下信息
ZOOMAIN = "-Dzookeeper.4lw.commands.whitelist=*${ZOOMAIN}"
shell終端輸入:echo wchc | nc localhost 2181
11.13 wchp命令
查看服務上有多少個節點;
wchp:通過路徑分組,列出所有的watch的session id信息
問題:
wchp is not executer beacues it is not in the whitelist
解決方法:
#修改啟動指令 zkServer.sh
#注意找到這個信息
else
echo "JMX disabled by user request" > & 2
ZOOMAIN = "org.apache.zookeeper.server.quorum.QuorumPeerMain"
fi
# 添加如下信息
ZOOMAIN = "-Dzookeeper.4lw.commands.whitelist=*${ZOOMAIN}"
shell終端輸入:echo wchp | nc localhost 2181
11.14 mntr命令
mntr:獵虎服務器的健康狀態
屬性 | 含義 |
---|---|
zk_version | 版本 |
zk_avg_latency | 平均延時 |
zk_max_latency | 最大延時 |
zk_min_latency | 最小延時 |
zk_packets_received | 收包數 |
zk_num_alive_connections | 連接數 |
zk_outstanding_requests | 堆積請求數 |
zk_znode_count | znode數量 |
zk_watch_count | watch數量 |
zk_ephemreals_count | 臨時節點 |
zk_approximate_data_size | 數據大小 |
zk_open_file_decriptor_count | 打開的文件描述符數量 |
zk_max_file_descriptor_count | 最大文件描述數量 |
zk_server_state | leader/follower數量 |
shell終端輸入:echo mntr | nc localhost 2181