经过./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