經過./zkCli.sh
打開 zk的客戶端進行命令行後臺node
進入 zookeeper安裝的 bin目錄,ls會看到以下:git
鍵入:
zkCli.sh
,出現如圖說明已是鏈接狀態github
ls
與 ls2
命令docker
ls path [watch]安全
ls2 path [watch]服務器
鍵入:ls /
session
會看到有 dubbo,zookeeper,test,這裏咱們吧 dubbo和 test先忽略,這是以前項目中使用,後續會介紹到;併發
這裏咱們先關注 zookeeper 節點 ;分佈式
咱們若是想看zookeeper下面還有什麼,咱們能夠鍵入: ls /zookeeper
,會看到一個quota目錄,quota目錄是 zookeeper一個節點;
下面咱們看下ls2
命令:
會發現除了顯示了quota節點之外還出現了一些節點的狀態信息;下面會說到;
get
與 stat
命令stat 就是 status 的簡寫,鍵入:
stat /zookeeper
能夠看到ls2
與stat
命令輸出的基本是同樣的;也就是說ls2
整合了stat
命令;
get
:鍵入get /zookeeper
這個命令會把當前節點中的數據取出來,當前節點數據爲空;
cZxid
:節點Id
ctime
:這個節點建立的時間
mZxid
:修改以後的 id
mtime
:修改的時間,若是沒有被修改就是和建立時間是一致的;
pZxid
:子節點 id
cversion
:子節點的版本,若是子節點發生變化這個值就會發生變化
dataVersion
:當前節點一個數據的版本號,若是當前節點的數據被修改這個值會累加1;
aclVersion
:權限版本,若是權限發生變化會累加1
ephemeralOwner
:臨時節點和持久節點之間的區別
dataLength
:數據長度
numChildren
:子節點數量
客戶端與服務端之間的鏈接存在會話
每一個會話均可以設置一個超時時間
心跳結束,session則過時
session過時,則臨時節點 znode 會被拋棄
心跳機制:客戶端向服務端發送 ping包請求
create命令
create [-s] [-e] path data acl
-s: 建立順序節點
-e: 建立臨時節點
path: 在哪裏建立
data: 給這個建立的節點添加的數據
acl: 建立節點的權限
鍵入: create /myzk myzk-data
能夠看到cversion
和dataVersion
都是 0;
建立一個臨時節點:
鍵入:create -e /myzk/tmp myzk-data
子節點的版本號由 0 變爲 1;
這個 tmp目錄是以前咱們建立的臨時節點,能夠看到ephemeralOwner
這個的值是0x100019e2b730001
而不是持久節點的0x0
,這就是持久節點和臨時節點的區別;
刪除臨時節點: ctrl+c
斷開鏈接;,再次進入,再次查看ls /myzk
可能還會有,由於是有心跳檢測的(時間差),等待一會再次查看tmp節點就會消失;
建立順序節點:
鍵入: create -s /myzk/sec seq
逐漸累加的;sec0000000001,sec0000000002,sec0000000003 …...這就是建立了臨時節點;
set命令
set path data [version]
先看下 myzk 節點下數據的值爲 myzk-data,dataversion的是 0;cversion是 4,由於上面咱們建立了1 個臨時節點和3 個順序節點;
鍵入: set /myzk new-data
而後我在 get /myzk
能夠看到當前節點的數據更新爲 new-data ; dataVersion 的值爲 1(樂觀鎖);
在高併發的狀況下,有不少的人對這個節點進行設置(也就是 set),例如:set /myzk 123
,在大併發的狀況下這個值(dataVersion)一直是累加的,而後直接的覆蓋原來的值;若是按照順序來設置的話就要在後面加上一個版本號set /myzk 123 1
如今 dataVersion的值變爲了 2;若是說我旁邊還有別的用戶也進行了這種操做,他獲取的時候版本號也是以前沒有修改的版本號也是 1;那麼如今他的實際版號已經由 1 變成了 2;那麼這個用戶繼續操做的話就會報一個錯;
version No is not valid : /myzk
咱們必須使用最新的版本號才能進行更新,這也是樂觀鎖最經常使用的一種方式;
delete命令
delete path [version]
首先查看一下 myzk節點下有多少子節點
能夠看到有:[sec0000000003, tmp, sec0000000001, sec0000000002]
那咱們下面來刪除一個:
鍵入: delete /myzk/sec0000000001
這樣就被刪除掉了,也就是說咱們不指定節點的話是能夠直接刪除掉的;
那下面咱們指定一個節點版本號進行刪除:咱們先把sec0000000002的版本號更新一下
首先鍵入: set /myzk/sec0000000002 123
這時 get //myzk/sec0000000002
能夠看到 dataVersion 的由 0 變爲了 1;
若是咱們仍是按老的版本號進行刪除也是會報version No is not valid : /myzk/sec0000000002
例如: delete /myzk/sec0000000002 0
;由於這時的版本號已經更新爲 1 了;
因此咱們鍵入:delete /myzk/sec0000000002 1
針對每一個節點的操做,都會有一個監督者 watcher,也能夠理解爲一個觸發器,當咱們的節點發生變化的時候,例如建立,刪除,修改等..都會觸發 watcher事件(包括父節點,子節點)
zk中的 watcher是一次性的,觸發後當即銷燬;
針對不一樣類型的操做,觸發的 watcher 事件也不一樣;
經過 get path [watch]設置 watcher
這只是其中一種,後面會講到其餘的設置 watcher事件的方式
watcher事件類型
咱們將以前建立的/myzk 節點刪除掉;演示:
這裏就觸發了一個NodeCreated事件;
這一次給節點去設置值是沒有觸發 watcher事件的,由於上一次設置的事件是一次性的;因此此次須要從新設置 watcher事件;咱們用另外一種方式去設置watcher事件
鍵入:get /myzk watch
再次去設置節點值的時候就會觸發 watcher事件;並且類型是NodeDataChanged
咱們跟上面同樣仍是要先設置節點事件,
鍵入: get /myzk watch
咱們上面演示的全部都是根據父節點來增刪改的;下面咱們看看子節點的 watcher事件
鍵入: ls /myzk watch
而後再/myzk節點下建立子節點,create /myzk/abc 88
這裏說一下爲何刪除和建立都是觸發NodeChildrenChanged,由於他們是子節點,子節點和父節點要區分開來,
父節點刪除和新增的話對應的是 delete 和 create;對於父節點來講我不須要去關注額外的東西,子節點我無論你是去建立仍是刪除對於我父節點來講我只須要給個人客戶端響應一個NodeChildrenChanged事件,至於發生什麼事件我不須要過問太多;
在這裏並無觸發 watch事件;這也是 zk的一個機制;在設置值得時候要把子節點當作父節點來對待,設置方式:
get /myzk/xyz watch
,而後 set /myzk/xyz/ 8080
這就是修改(set)和建立(create),刪除(delete)的不一樣之處;在修改子節點想觸發 watch 事件必需要按照父節點的方式進行;
統一資源配置
當主機更新節點爲新的配置信息時會觸發 watcher 事件,客戶端 1, 客戶端 2, 客戶端 3會監聽 watcher事件,並更新配置;
ACL命令行
getAcl:獲取某個節點的 acl權限信息
getAcl path
鍵入: getAcl /myzk/abc
setAcl:設置某個節點的 acl權限信息
addauth: 輸入認證受權信息,註冊時輸入明文密碼(登陸)可是在 zk的系統裏,密碼是以加密的形式存在的;
ACL 的構成
zk的 acl 經過[scheme:id :permissions]來構成權限列表
Scheme:表明採用某種權限機制
id:表明容許訪問的用戶
Permissions:權限組合字符串
Scheme
world: world下只有一個 id,即只有一個用戶,也就是 anyone,那麼組合的寫法就是 world:anyone:[permissions]
auth:表明認證登陸,須要註冊用戶有權限就能夠,形式爲 auth:user:password:[permissions]
digest:須要對密碼加密才能訪問,組合形式爲 digest:username:BASE64(SHA1(password)):[permissions]
auth和 digest的區別之處是:auth 的登陸密碼可使明文,而 digest密碼是要加過密的;後續例子中演示
ip:當設置爲 ip 指定的 ip地址,此時限制 ip進行訪問,好比 ip:192.168.1.1:[permissions]
super: 表明超級管理員,擁有全部的權限
Permissions
權限字符串縮寫:crdwa
CREATE:建立子節點
若是某個用戶擁有了Create權限也就是擁有了建立當前節點子節點的權限;
READ:獲取當前節點/子節點;也就是讀取權限;
WRITE:設置節點數據;也就是寫權限;
DELETE:刪除子節點;
ADMIN: 設置權限;
建立時會有一個默認權限,全部的匿名用戶均可以對這個節點進行操做,擁有全部權限
下面設置一下權限:
crwa: 建立/讀/寫/admin(設置權限),這裏是沒有刪除的權限;注意刪除是指刪除子節點的權限,my_zk是全部權限都有,多以這裏abc節點是能夠刪除的;這裏是指abc節點只有crwa權限;下面演示一下:
這裏沒有權限刪除節點/my_zk/abc/xyz
;由於這個abc節點是有admin權限的,因此咱們能夠從新能夠設置權限的;
auth:user:pwd:cdrwa
跟節點下有dubbo, zookeeper, test, testnode, myzk
,myzk節點下有 abc節點;
abc有默認的 cdrwa權限;下面咱們使用 auth方式給 abc節點設置權限;
setAcl /myzk/abc auth:haoxy:haoxy:cdrwa
其中 haoxy:haoxy表示用戶名和密碼
Acl is not valid : /myzk/abc
:這句話的意思是咱們如今尚未註冊;
經過addauth digest haoxy:haoxy
來進行註冊;
而後咱們再去設置權限
使用getAcl /myzk/abc
查看:以下
其中 haoxy
表示用戶名,Sm6Y7C7Lz+Zw3Dg5QPqU15Vy1Vg=
表示加密後(SHA1和 BASE64)的密碼(先保存一下後面會用到)
第一次註冊和登陸以後,後面就能夠省略不寫了,例如setAcl /myzk/abc auth::cdrwa
由於他是跟着第一登陸註冊的時候來的;退出 ctrl+c,以前的用戶就會自動的退出;
digest:user:BASE64(SHA1(pwd)):cdrwa
退出當前用戶;這裏咱們從新建立一個節點test
鍵入:setAcl /myzk/test digest:haoxy:Sm6Y7C7Lz+Zw3Dg5QPqU15Vy1Vg=:cdra
haoxy
:用戶名,Sm6Y7C7Lz+Zw3Dg5QPqU15Vy1Vg=
加密後的密碼
這個時候咱們鍵入:get /myzk/test
是會提示:Authentication is not valid : /myzk/test
權限不足
因此咱們仍是須要經過:addauth digest haoxy:haoxy
登陸;上一步 setAcl能夠說是註冊;
注意這裏是經過明文,咱們不可能讓用戶經過密碼登陸,再次 get /myzk/test
就能夠正常顯示數據
上面咱們給寫權限,下面咱們測試一下寫權限是否能寫:
正式如我所願,是沒有寫權限的;
這裏 delete 是有權限的,這也是正如咱們所願;
addauth digest user:pwd
上面咱們也介紹了addauth,語法: addauth digest haoxy:haoxy
zk能夠經過它自身提供的簡寫命令與服務器進行交互
須要用到nc 命令,安裝:yum install nc
語法: echo [commond] | nc [ip] [port]
命令 | 示例 | 描述 |
---|---|---|
conf | echo conf | nc localhost 2181 | 輸出相關服務配置的詳細信息。好比端口、zk數據及日誌配置路徑、最大鏈接數,session超時時間、serverId等 |
cons | echo cons | nc localhost 2181 | 列出全部鏈接到這臺服務器的客戶端鏈接/會話的詳細信息 包括「接受/發送」的包數量、session id 、操做延遲、最後的操做執行等信息 |
crst | Echo crst | nc localhost 2181 | 重置當前這臺服務器全部鏈接/會話的統計信息 |
dump | echo dump | localhost 2181 | 列出未經處理的會話和臨時節點(只在leader上有效) |
envi | echo dump | localhost 2181 | 輸出關於服務器的環境詳細信息(不一樣於conf命令),好比host.name、java.version、java.home、user.dir=/data/zookeeper-3.4.6/bin之類信息 |
ruok | echo ruok | localhost 2181 | 測試服務是否處於正確運行狀態。若是正常返回"imok",不然返回空。 |
srst | echo srst | localhost 2181 | 重置服務器的統計信息 |
srvr | echo srvr | localhost 2181 | 輸出服務器的詳細信息。zk版本、接收/發送包數量、鏈接數、模式(leader/follower)、節點總數。 |
stat | echo stat | localhost 2181 | 輸出服務器的詳細信息:接收/發送包數量、鏈接數、模式(leader/follower)、節點總數、延遲。 全部客戶端的列表。 |
wchs | echo wchs | localhost 2181 | 列出服務器watches的簡潔信息:鏈接總數、watching節點總數和watches總數 |
wchc | echo wchc | localhost 2181 | 經過session分組,列出watch的全部節點,它的輸出是一個與 watch 相關的會話的節點列表。若是watches數量很大的話,將會產生很大的開銷,會影響性能,當心使用。 |
wchp | echo wchp | nc localhost 2181 | 經過路徑分組,列出全部的 watch 的session id信息。它輸出一個與 session 相關的路徑。若是watches數量很大的話,將會產生很大的開銷,會影響性能,當心使用。 |
mntr | echo mntr | nc localhost 2181 | 列出集羣的健康狀態。包括「接受/發送」的包數量、操做延遲、當前服務模式(leader/follower)、節點總數、watch總數、臨時節點總數。 |
若是你在輸入四字命令時出現如下提示:
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,你進入容器到 conf文件夾下是找不到 zoo.cfg文件的;
那麼我們就要使用映射的方式:
建立配置文件 zoo.cfg,將上面的內容拷貝到 zoo.cfg中,編寫 docker-compose,配置volumes ,內容以下:
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