zk常用命令行操作
-
通過
./zkCli.sh
打開 zk的客戶端進行命令行后臺進入 zookeeper安裝的 bin目錄,ls會看到如下:
鍵入:
zkCli.sh
,出現(xiàn)如圖說明已經(jīng)是連接狀態(tài)
-
ls
與ls2
命令ls path [watch]
ls2 path [watch]
鍵入:ls /
會看到有 dubbo,zookeeper,test,這里我們吧 dubbo和 test先忽略,這是之前項目中使用,后續(xù)會介紹到;
這里我們先關(guān)注 zookeeper 節(jié)點 ;
我們?nèi)绻肟磟ookeeper下面還有什么,我們可以鍵入: ls /zookeeper
,會看到一個quota目錄,quota目錄是 zookeeper一個節(jié)點;
下面我們看下ls2
命令:
會發(fā)現(xiàn)除了顯示了quota節(jié)點以外還出現(xiàn)了一些節(jié)點的狀態(tài)信息;下面會說到;
-
get
與stat
命令
stat 就是 status 的簡寫,鍵入:
stat /zookeeper
可以看到ls2
與stat
命令輸出的基本是一樣的;也就是說ls2
整合了stat
命令;
get
:鍵入get /zookeeper
這個命令會把當(dāng)前節(jié)點中的數(shù)據(jù)取出來,當(dāng)前節(jié)點數(shù)據(jù)為空;
cZxid
:節(jié)點Id
ctime
:這個節(jié)點創(chuàng)建的時間
mZxid
:修改之后的 id
mtime
:修改的時間,如果沒有被修改就是和創(chuàng)建時間是一致的;
pZxid
:子節(jié)點 id
cversion
:子節(jié)點的版本,如果子節(jié)點發(fā)生變化這個值就會發(fā)生變化
dataVersion
:當(dāng)前節(jié)點一個數(shù)據(jù)的版本號,如果當(dāng)前節(jié)點的數(shù)據(jù)被修改這個值會累加1;
aclVersion
:權(quán)限版本,如果權(quán)限發(fā)生變化會累加1
ephemeralOwner
:臨時節(jié)點和持久節(jié)點之間的區(qū)別
dataLength
:數(shù)據(jù)長度
numChildren
:子節(jié)點數(shù)量
Session的基本原理
客戶端與服務(wù)端之間的連接存在會話
每個會話都可以設(shè)置一個超時時間
心跳結(jié)束,session則過期
session過期,則臨時節(jié)點 znode 會被拋棄
心跳機制:客戶端向服務(wù)端發(fā)送 ping包請求
zk常用命令行操作2
-
create命令
create [-s] [-e] path data acl
-s: 創(chuàng)建順序節(jié)點
-e: 創(chuàng)建臨時節(jié)點
path: 在哪里創(chuàng)建
data: 給這個創(chuàng)建的節(jié)點添加的數(shù)據(jù)
acl: 創(chuàng)建節(jié)點的權(quán)限
鍵入:
create /myzk myzk-data
可以看到cversion
和dataVersion
都是 0;
創(chuàng)建一個臨時節(jié)點:
鍵入:create -e /myzk/tmp myzk-data
子節(jié)點的版本號由 0 變?yōu)?1;
這個 tmp目錄是之前我們創(chuàng)建的臨時節(jié)點,可以看到ephemeralOwner
這個的值是0x100019e2b730001
而不是持久節(jié)點的0x0
,這就是持久節(jié)點和臨時節(jié)點的區(qū)別;
刪除臨時節(jié)點: ctrl+c
斷開連接;,再次進入,再次查看ls /myzk
可能還會有,因為是有心跳檢測的(時間差),等待一會再次查看tmp節(jié)點就會消失;
創(chuàng)建順序節(jié)點:
鍵入: create -s /myzk/sec seq
逐漸累加的;sec0000000001,sec0000000002,sec0000000003 …...這就是創(chuàng)建了臨時節(jié)點;
-
set命令
set path data [version]
先看下 myzk 節(jié)點下數(shù)據(jù)的值為 myzk-data,dataversion的是 0;cversion是 4,因為上面我們創(chuàng)建了1 個臨時節(jié)點和3 個順序節(jié)點;
鍵入: set /myzk new-data
然后我在 get /myzk
可以看到當(dāng)前節(jié)點的數(shù)據(jù)更新為 new-data ; dataVersion 的值為 1(樂觀鎖);
在高并發(fā)的情況下,有很多的人對這個節(jié)點進行設(shè)置(也就是 set),例如:set /myzk 123
,在大并發(fā)的情況下這個值(dataVersion)一直是累加的,然后直接的覆蓋原來的值;如果按照順序來設(shè)置的話就要在后面加上一個版本號set /myzk 123 1
現(xiàn)在 dataVersion的值變?yōu)榱?2;如果說我旁邊還有別的用戶也進行了這種操作,他獲取的時候版本號也是之前沒有修改的版本號也是 1;那么現(xiàn)在他的實際版號已經(jīng)由 1 變成了 2;那么這個用戶繼續(xù)操作的話就會報一個錯;
version No is not valid : /myzk
我們必須使用最新的版本號才能進行更新,這也是樂觀鎖最常用的一種方式;
-
delete命令
delete path [version]
首先查看一下 myzk節(jié)點下有多少子節(jié)點
可以看到有:[sec0000000003, tmp, sec0000000001, sec0000000002]
那我們下面來刪除一個:
鍵入: delete /myzk/sec0000000001
這樣就被刪除掉了,也就是說我們不指定節(jié)點的話是可以直接刪除掉的;
那下面我們指定一個節(jié)點版本號進行刪除:我們先把sec0000000002的版本號更新一下
首先鍵入: set /myzk/sec0000000002 123
這時 get //myzk/sec0000000002
可以看到 dataVersion 的由 0 變?yōu)榱?1;
如果我們還是按老的版本號進行刪除也是會報version No is not valid : /myzk/sec0000000002
例如: delete /myzk/sec0000000002 0
;因為這時的版本號已經(jīng)更新為 1 了;
所以我們鍵入:delete /myzk/sec0000000002 1
zk特性 watcher機制
針對每個節(jié)點的操作,都會有一個監(jiān)督者 watcher,也可以理解為一個觸發(fā)器,當(dāng)我們的節(jié)點發(fā)生變化的時候,例如創(chuàng)建,刪除,修改等..都會觸發(fā) watcher事件(包括父節(jié)點,子節(jié)點)
zk中的 watcher是一次性的,觸發(fā)后立即銷毀;
-
針對不同類型的操作,觸發(fā)的 watcher 事件也不同;
- (子)節(jié)點創(chuàng)建事件
- (子)節(jié)點刪除事件
- (子)節(jié)點數(shù)據(jù)變化事件
watcher命令行
-
通過 get path [watch]設(shè)置 watcher
這只是其中一種,后面會講到其他的設(shè)置 watcher事件的方式
watcher事件類型
- 創(chuàng)建父節(jié)點觸發(fā): NodeCreated
我們將之前創(chuàng)建的/myzk 節(jié)點刪除掉;演示:
這里就觸發(fā)了一個NodeCreated事件;
- 修改父節(jié)點數(shù)據(jù)觸發(fā): NodeDataChanged
這一次給節(jié)點去設(shè)置值是沒有觸發(fā) watcher事件的,因為上一次設(shè)置的事件是一次性的;所以這次需要重新設(shè)置 watcher事件;我們用另一種方式去設(shè)置watcher事件
鍵入:get /myzk watch
再次去設(shè)置節(jié)點值的時候就會觸發(fā) watcher事件;而且類型是NodeDataChanged
- 刪除父節(jié)點觸發(fā):NodeDeleted
我們跟上面一樣還是要先設(shè)置節(jié)點事件,
鍵入: get /myzk watch
我們上面演示的所有都是根據(jù)父節(jié)點來增刪改的;下面我們看看子節(jié)點的 watcher事件
- ls為父節(jié)點設(shè)置 watcher,創(chuàng)建子節(jié)點觸發(fā) NodeChildrenChanged
鍵入: ls /myzk watch
然后再/myzk節(jié)點下創(chuàng)建子節(jié)點,create /myzk/abc 88
- ls為父節(jié)點設(shè)置 watcher,刪除子節(jié)點觸發(fā) NodeChildrenChanged
這里說一下為什么刪除和創(chuàng)建都是觸發(fā)NodeChildrenChanged,因為他們是子節(jié)點,子節(jié)點和父節(jié)點要區(qū)分開來,
父節(jié)點刪除和新增的話對應(yīng)的是 delete 和 create;對于父節(jié)點來說我不需要去關(guān)注額外的東西,子節(jié)點我不管你是去創(chuàng)建還是刪除對于我父節(jié)點來說我只需要給我的客戶端響應(yīng)一個NodeChildrenChanged事件,至于發(fā)生什么事件我不需要過問太多;
- ls為父節(jié)點設(shè)置 watcher,修改子節(jié)點不觸發(fā)事件
在這里并沒有觸發(fā) watch事件;這也是 zk的一個機制;在設(shè)置值得時候要把子節(jié)點當(dāng)做父節(jié)點來對待,設(shè)置方式:
get /myzk/xyz watch
,然后 set /myzk/xyz/ 8080
這就是修改(set)和創(chuàng)建(create),刪除(delete)的不同之處;在修改子節(jié)點想觸發(fā) watch 事件必須要按照父節(jié)點的方式進行;
watcher使用場景
-
統(tǒng)一資源配置
當(dāng)主機更新節(jié)點為新的配置信息時會觸發(fā) watcher 事件,客戶端 1, 客戶端 2, 客戶端 3會監(jiān)聽 watcher事件,并更新配置;
ACL(access control lists)權(quán)限控制
- 針對節(jié)點可以設(shè)置相關(guān)的讀寫等權(quán)限,目的為了保障數(shù)據(jù)安全性
- 權(quán)限 permissions可以指定不同的權(quán)限范圍以及角色(跟 shiro很相似)
ACL命令行
-
getAcl:獲取某個節(jié)點的 acl權(quán)限信息
getAcl path
鍵入:
getAcl /myzk/abc
setAcl:設(shè)置某個節(jié)點的 acl權(quán)限信息
addauth: 輸入認證授權(quán)信息,注冊時輸入明文密碼(登錄)但是在 zk的系統(tǒng)里,密碼是以加密的形式存在的;
ACL 的構(gòu)成
-
zk的 acl 通過[scheme:id :permissions]來構(gòu)成權(quán)限列表
Scheme:代表采用某種權(quán)限機制
id:代表允許訪問的用戶
Permissions:權(quán)限組合字符串
Scheme
world: world下只有一個 id,即只有一個用戶,也就是 anyone,那么組合的寫法就是 world:anyone:[permissions]
auth:代表認證登錄,需要注冊用戶有權(quán)限就可以,形式為 auth:user:password:[permissions]
-
digest:需要對密碼加密才能訪問,組合形式為 digest:username:BASE64(SHA1(password)):[permissions]
auth和 digest的區(qū)別之處是:auth 的登錄密碼可以使明文,而 digest密碼是要加過密的;后續(xù)例子中演示
ip:當(dāng)設(shè)置為 ip 指定的 ip地址,此時限制 ip進行訪問,比如 ip:192.168.1.1:[permissions]
super: 代表超級管理員,擁有所有的權(quán)限
Permissions
權(quán)限字符串縮寫:crdwa
-
CREATE:創(chuàng)建子節(jié)點
如果某個用戶擁有了Create權(quán)限也就是擁有了創(chuàng)建當(dāng)前節(jié)點子節(jié)點的權(quán)限;
READ:獲取當(dāng)前節(jié)點/子節(jié)點;也就是讀取權(quán)限仅孩;
WRITE:設(shè)置節(jié)點數(shù)據(jù)磷支;也就是寫權(quán)限歇竟;
DELETE:刪除子節(jié)點;
ADMIN: 設(shè)置權(quán)限静袖;
ACL命令行學(xué)習(xí)
- world:anyone :crdwa
創(chuàng)建時會有一個默認權(quán)限,所有的匿名用戶都可以對這個節(jié)點進行操作朋鞍,擁有所有權(quán)限
下面設(shè)置一下權(quán)限:
crwa: 創(chuàng)建/讀/寫/admin(設(shè)置權(quán)限),這里是沒有刪除的權(quán)限;注意刪除是指刪除子節(jié)點的權(quán)限妥箕,my_zk是所有權(quán)限都有滥酥,多以這里abc節(jié)點是可以刪除的;這里是指abc節(jié)點只有crwa權(quán)限畦幢;下面演示一下:
這里沒有權(quán)限刪除節(jié)點/my_zk/abc/xyz
;因為這個abc節(jié)點是有admin權(quán)限的坎吻,所以我們可以重新可以設(shè)置權(quán)限的只冻;
-
auth:user:pwd:cdrwa
跟節(jié)點下有
dubbo, zookeeper, test, testnode, myzk
,myzk節(jié)點下有 abc節(jié)點;abc有默認的 cdrwa權(quán)限;下面我們使用 auth方式給 abc節(jié)點設(shè)置權(quán)限;
setAcl /myzk/abc auth:haoxy:haoxy:cdrwa
其中 haoxy:haoxy表示用戶名和密碼Acl is not valid : /myzk/abc
:這句話的意思是我們現(xiàn)在還沒有注冊;通過
addauth digest haoxy:haoxy
來進行注冊;然后我們再去設(shè)置權(quán)限
使用
getAcl /myzk/abc
查看:如下其中
haoxy
表示用戶名,Sm6Y7C7Lz+Zw3Dg5QPqU15Vy1Vg=
表示加密后(SHA1和 BASE64)的密碼(先保存一下后面會用到)第一次注冊和登錄之后,后面就可以省略不寫了,例如
setAcl /myzk/abc auth::cdrwa
因為他是跟著第一登錄注冊的時候來的;退出 ctrl+c,之前的用戶就會自動的退出; -
digest:user:BASE64(SHA1(pwd)):cdrwa
退出當(dāng)前用戶;這里我們重新創(chuàng)建一個節(jié)點
test
鍵入:
setAcl /myzk/test digest:haoxy:Sm6Y7C7Lz+Zw3Dg5QPqU15Vy1Vg=:cdra
haoxy
:用戶名,Sm6Y7C7Lz+Zw3Dg5QPqU15Vy1Vg=
加密后的密碼這個時候我們鍵入:
get /myzk/test
是會提示:Authentication is not valid : /myzk/test
權(quán)限不足所以我們還是需要通過:
addauth digest haoxy:haoxy
登錄;上一步 setAcl可以說是注冊;注意這里是通過明文,我們不可能讓用戶通過密碼登錄,再次
get /myzk/test
就可以正常顯示數(shù)據(jù)上面我們給寫權(quán)限,下面我們測試一下寫權(quán)限是否能寫:
正式如我所愿,是沒有寫權(quán)限的;
這里 delete 是有權(quán)限的,這也是正如我們所愿;
-
addauth digest user:pwd
上面我們也介紹了addauth,語法: addauth digest haoxy:haoxy
zk四字命令
zk可以通過它自身提供的簡寫命令與服務(wù)器進行交互
需要用到nc 命令帜慢,安裝:yum install nc
-
語法: echo [commond] | nc [ip] [port]
命令 示例 描述 conf echo conf | nc localhost 2181 輸出相關(guān)服務(wù)配置的詳細信息。比如端口变逃、zk數(shù)據(jù)及日志配置路徑贝搁、最大連接數(shù)吗氏,session超時時間、serverId等 cons echo cons | nc localhost 2181 列出所有連接到這臺服務(wù)器的客戶端連接/會話的詳細信息 包括“接受/發(fā)送”的包數(shù)量雷逆、session id 、操作延遲污尉、最后的操作執(zhí)行等信息 crst Echo crst | nc localhost 2181 重置當(dāng)前這臺服務(wù)器所有連接/會話的統(tǒng)計信息 dump echo dump | localhost 2181 列出未經(jīng)處理的會話和臨時節(jié)點(只在leader上有效) envi echo dump | localhost 2181 輸出關(guān)于服務(wù)器的環(huán)境詳細信息(不同于conf命令)膀哲,比如host.name、java.version被碗、java.home某宪、user.dir=/data/zookeeper-3.4.6/bin之類信息 ruok echo ruok | localhost 2181 測試服務(wù)是否處于正確運行狀態(tài)。如果正常返回"imok"锐朴,否則返回空兴喂。 srst echo srst | localhost 2181 重置服務(wù)器的統(tǒng)計信息 srvr echo srvr | localhost 2181 輸出服務(wù)器的詳細信息。zk版本、接收/發(fā)送包數(shù)量衣迷、連接數(shù)畏鼓、模式(leader/follower)、節(jié)點總數(shù)壶谒。 stat echo stat | localhost 2181 輸出服務(wù)器的詳細信息:接收/發(fā)送包數(shù)量云矫、連接數(shù)、模式(leader/follower)汗菜、節(jié)點總數(shù)让禀、延遲。 所有客戶端的列表陨界。 wchs echo wchs | localhost 2181 列出服務(wù)器watches的簡潔信息:連接總數(shù)巡揍、watching節(jié)點總數(shù)和watches總數(shù) wchc echo wchc | localhost 2181 通過session分組,列出watch的所有節(jié)點菌瘪,它的輸出是一個與 watch 相關(guān)的會話的節(jié)點列表吼肥。如果watches數(shù)量很大的話,將會產(chǎn)生很大的開銷麻车,會影響性能缀皱,小心使用。 wchp echo wchp | nc localhost 2181 通過路徑分組动猬,列出所有的 watch 的session id信息啤斗。它輸出一個與 session 相關(guān)的路徑。如果watches數(shù)量很大的話赁咙,將會產(chǎn)生很大的開銷钮莲,會影響性能,小心使用彼水。 mntr echo mntr | nc localhost 2181 列出集群的健康狀態(tài)崔拥。包括“接受/發(fā)送”的包數(shù)量、操作延遲凤覆、當(dāng)前服務(wù)模式(leader/follower)链瓦、節(jié)點總數(shù)、watch總數(shù)盯桦、臨時節(jié)點總數(shù)慈俯。
如果你在輸入四字命令時出現(xiàn)以下提示:
stat is not executed because it is not in the whitelist.
在 zoo.cfg配置文件中加入4lw.commands.whitelist=*
,這句話就是將四字命令加入到白名單中
例如我的配置:
tickTime = 2000
dataDir = /data
dataLogDir = /datalog
tickTime = 6000
clientPort = 2181
initLimit = 5
syncLimit = 2
4lw.commands.whitelist=*
解決使用 docker安裝 zookeeper 時的四字命令問題
但是如果你是使用 docker 鏡像安裝的 zookeeper,你進入容器到 conf文件夾下是找不到 zoo.cfg文件的;
那么咱們就要使用映射的方式:
創(chuàng)建配置文件 zoo.cfg,將上面的內(nèi)容拷貝到 zoo.cfg中,編寫 docker-compose,配置volumes ,內(nèi)容如下:
version: '2'
services:
zookeeper:
image: zookeeper
restart: always
container_name: zookeeper
volumes:
- ./config:/conf
ports:
- "2181:2181"
environment:
ZOO_MY_ID: 1
將之前的容器,鏡像刪除,重新運行 docker-compose up -d 命令,在次使用四字命令即 OK