通过./zkCli.sh打开zookeeper的客户端进行命令行后台
常用命令
ls与ls2
ls命令用来查看当前zookeeper中所包含的内容
如ls /
ls /zookeeper
ls /zookeeper/quato
ls2是ls的升级版,列出子节点的同时列出子节点的状态信息
其中
cZxid:节点被创建时的事务ID
ctime:节点创建时间
mZxid:最近一次更新时的事务ID
mtime:最近一次更新时间
pZxid:该节点的子节点列表最近一次被修改的事务ID,添加删除子节点会影响该值
cversion:子节点版本号
dataVersion:数据版本号
aclVersion:ACL版本号
ephemeralOwner:创建临时节点的事务ID,如果是持久节点,则该值为0x0
dataLength:当前节点的数据长度
numChildren:当前节点的子节点数目
get与stat命令
get 可以列出指定节点的数据
当前节点为空,所以没有显示数据
stat 列出指定节点的状态信息,或者说是元书籍信息
create命令
create [-s] [-e] path data acl
s:可选,表示该节点为顺序节点
e:可选,表示该节点为临时节点
path:节点路径
data:节点数据
acl:访问控制列表
[zk: localhost:2181(CONNECTED) 16] ls /
[zj, zookeeper]
[zk: localhost:2181(CONNECTED) 17] create -e /zj/node1 1
Created /zj/node1
[zk: localhost:2181(CONNECTED) 18] create -e /zj/node2 2
Created /zj/node2
[zk: localhost:2181(CONNECTED) 19] create -s /zj/node3 3
Created /zj/node30000000002
[zk: localhost:2181(CONNECTED) 20] create -s /zj/node3 3
Created /zj/node30000000003
[zk: localhost:2181(CONNECTED) 21] create -s /zj/node3 3
Created /zj/node30000000004
[zk: localhost:2181(CONNECTED) 22] create -s /zj/node3 3
Created /zj/node30000000005
[zk: localhost:2181(CONNECTED) 23] create -s /zj/node3 3
Created /zj/node30000000006
[zk: localhost:2181(CONNECTED) 24] create -s /zj/node3 3
Created /zj/node30000000007
[zk: localhost:2181(CONNECTED) 25] create -s /zj/node3 3
Created /zj/node30000000008
[zk: localhost:2181(CONNECTED) 26] ls /zj
[node30000000006, node30000000005, node2, node30000000004, node30000000003, node30000000002, node1, node30000000008, node30000000007]
[zk: localhost:2181(CONNECTED) 27] ls2 /zj
[node30000000006, node30000000005, node2, node30000000004, node30000000003, node30000000002, node1, node30000000008, node30000000007]
cZxid = 0x4
ctime = Thu Apr 19 17:05:23 CST 2018
mZxid = 0x4
mtime = Thu Apr 19 17:05:23 CST 2018
pZxid = 0xd
cversion = 9
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 9
[zk: localhost:2181(CONNECTED) 28] ls2 /zj/node
node30000000006 node30000000005 node2 node30000000004
node30000000003 node30000000002 node1 node30000000008
node30000000007
[zk: localhost:2181(CONNECTED) 28] ls2 /zj/node2
[]
cZxid = 0x6
ctime = Thu Apr 19 17:07:43 CST 2018
mZxid = 0x6
mtime = Thu Apr 19 17:07:43 CST 2018
pZxid = 0x6
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x1000022367c0000
dataLength = 1
numChildren = 0
set修改操作
set path data [version]
path 节点路径
data 新数据
version 版本号,要么不写,要么和上一次查询出的版本号一致,该操作会影响节点的mZxid、dataVersion和mtime属性
[zk: localhost:2181(CONNECTED) 30] set /zj/node1 new1
cZxid = 0x5
ctime = Thu Apr 19 17:07:32 CST 2018
mZxid = 0xe
mtime = Thu Apr 19 17:15:12 CST 2018
pZxid = 0x5
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x1000022367c0000
dataLength = 4
numChildren = 0
[zk: localhost:2181(CONNECTED) 31] set /zj/node1 new2 1
cZxid = 0x5
ctime = Thu Apr 19 17:07:32 CST 2018
mZxid = 0xf
mtime = Thu Apr 19 17:15:28 CST 2018
pZxid = 0x5
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x1000022367c0000
dataLength = 4
numChildren = 0
[zk: localhost:2181(CONNECTED) 32] set /zj/node1 new2 1
version No is not valid : /zj/node1
删除操作
delete
delete path [version]
path:要删除的节点的路径
version:可选,删除当前版本的路径,如果版本不对,不能删除
[zk: localhost:2181(CONNECTED) 39] delete /zj/node
node30000000006 node30000000005 node2 node30000000004
node30000000003 node30000000002 node1 node30000000008
node30000000007
[zk: localhost:2181(CONNECTED) 39] delete /zj/node1
[zk: localhost:2181(CONNECTED) 40] set /zj/node
node30000000006 node30000000005 node2 node30000000004
node30000000003 node30000000002 node30000000008 node30000000007
[zk: localhost:2181(CONNECTED) 40] set /zj/node2 newdata
cZxid = 0x6
ctime = Thu Apr 19 17:07:43 CST 2018
mZxid = 0x12
mtime = Thu Apr 19 17:21:59 CST 2018
pZxid = 0x6
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x1000022367c0000
dataLength = 7
numChildren = 0
[zk: localhost:2181(CONNECTED) 41] delete /zj/node2 0
version No is not valid : /zj/node2
rmr递归删除节点
rmr path
[zk: localhost:2181(CONNECTED) 44] ls /zj/node2
[]
[zk: localhost:2181(CONNECTED) 45] create /zj/node2/newnode1 1
Ephemerals cannot have children: /zj/node2/newnode1
[zk: localhost:2181(CONNECTED) 46] create /zj/node
node30000000006 node30000000005 node2 node30000000004
node30000000003 node30000000002 node30000000008 node30000000007
[zk: localhost:2181(CONNECTED) 46] create /zj/node2/newnode1/newnewnode 1
Node does not exist: /zj/node2/newnode1/newnewnode
[zk: localhost:2181(CONNECTED) 47] create /zj/node1 data1
Created /zj/node1
[zk: localhost:2181(CONNECTED) 48] ls2 /zj/node
node30000000006 node30000000005 node2 node30000000004
node30000000003 node30000000002 node1 node30000000008
node30000000007
[zk: localhost:2181(CONNECTED) 48] ls2 /zj/node1
[]
cZxid = 0x16
ctime = Thu Apr 19 17:26:33 CST 2018
mZxid = 0x16
mtime = Thu Apr 19 17:26:33 CST 2018
pZxid = 0x16
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 49] create /zj/node1/newnode1 nownode1
Created /zj/node1/newnode1
[zk: localhost:2181(CONNECTED) 50] create /zj/node1/newnode1/newnewnode1 nownode
[zk: localhost:2181(CONNECTED) 50] ls /zj/node
node30000000006 node30000000005 node2 node30000000004
node30000000003 node30000000002 node1 node30000000008
node30000000007
[zk: localhost:2181(CONNECTED) 50] ls /zj/node1
[newnode1]
[zk: localhost:2181(CONNECTED) 51] delete /zj/node1
Node not empty: /zj/node1
[zk: localhost:2181(CONNECTED) 52] rmr /zj/node1
临时节点不能有子节点,节点不为空不能删除,非得删除使用rmr
session原理
客户端与服务器之间的链接存在会话
每个会话都可以设置一个超时时间
心跳结束,session则过期
session过期,则临时节点znode会被抛弃
心跳机制:客户端向服务端的ping包请求
watcher机制
针对每个节点的操作,都会有一个监督者,就是watcher
当监控的某个对象(znode)发生了变化,则触发watcher事件
zookeeper中的watcher是一次性的,触发后立即销毁
父节点,子节点增删改都能触发其watcher
针对不同类型的操作,触发的watcher事件也不同,比如(子)节点创建事件、(子)节点删除事件、(子)节点数据变化事件
watcher命令行学习
通过get path [watch]设置watcher
通过ls path [watch]
通过ls2 path [watch]
通过stat path [watch]
父节点、子节点增删改操作都能触发watcher
watcher事件类型
创建父节点触发NodeCreated
[zk: localhost:2181(CONNECTED) 3] stat /zj watch
Node does not exist: /zj
[zk: localhost:2181(CONNECTED) 5] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 6] create /zj 123
WATCHER::
WatchedEvent state:SyncConnected type:NodeCreated path:/zj
Created /zj
节点数据改变NodeDataChanged
[zk: localhost:2181(CONNECTED) 12] get /zj watch
123456
cZxid = 0x25
ctime = Thu Apr 19 17:44:12 CST 2018
mZxid = 0x27
mtime = Thu Apr 19 17:48:00 CST 2018
pZxid = 0x25
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 13] set /zj 12345
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/zj
cZxid = 0x25
ctime = Thu Apr 19 17:44:12 CST 2018
mZxid = 0x28
mtime = Thu Apr 19 17:48:47 CST 2018
pZxid = 0x25
cversion = 0
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
节点删除事件NodeDeleted
[zk: localhost:2181(CONNECTED) 15] create /zj 123
Created /zj
[zk: localhost:2181(CONNECTED) 16] delete /zj
[zk: localhost:2181(CONNECTED) 17] create /zj 123456
Created /zj
[zk: localhost:2181(CONNECTED) 18] stat /zj watch
cZxid = 0x2c
ctime = Thu Apr 19 17:53:12 CST 2018
mZxid = 0x2c
mtime = Thu Apr 19 17:53:12 CST 2018
pZxid = 0x2c
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 19] delete /zj
WATCHER::
WatchedEvent state:SyncConnected type:NodeDeleted path:/zj
创建子节点NodeChildrenChanged
ls为父节点设置watch,创建子节点触发
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 1] create /zj 123
Created /zj
[zk: localhost:2181(CONNECTED) 2] ls /zj/ watch
Command failed: java.lang.IllegalArgumentException: Path must not end with / character
[zk: localhost:2181(CONNECTED) 3] ls /zj watch
[]
[zk: localhost:2181(CONNECTED) 4] create /zj/node1 node1
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/zj
Created /zj/node1
删除子节点NodeChildrenChanged
ls为父节点设置watcher,删除子节点触发
[zk: localhost:2181(CONNECTED) 5] ls /zj watch
[node1]
[zk: localhost:2181(CONNECTED) 6] delete /zj/node1
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/zj
修改子节点不触发事件
注意,ls为父节点设置watch,修改子节点不触发事件
针对子节点修改,要想触发事件,必须用stat或get,把子节点当父节点来用,才能触发
[zk: localhost:2181(CONNECTED) 7] create /zj/node1 123
Created /zj/node1
[zk: localhost:2181(CONNECTED) 8] ls /zj watch
[node1]
[zk: localhost:2181(CONNECTED) 9] set /zj/node1 123456
cZxid = 0x33
ctime = Thu Apr 19 18:04:39 CST 2018
mZxid = 0x34
mtime = Thu Apr 19 18:04:52 CST 2018
pZxid = 0x33
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
wacher使用场景
统一资源配置
ACL(access control lists)权限控制
针对节点可以设置相关读写等权限,目的为了保障数据安全性
权限permissions可以指定不同的权限范围以及角色
ACL命令行
getAcl
获取某个节点的acl权限信息
getAcl path
setAcl
设置某个节点的acl权限信息
setAcl path acl
addauth
输入认证授权信息,注册时输入明文密码(登录),但是在zookeeper的系统里,密码是以加密的形式存在的
addauth sheme auth
ACL构成
zookeeper的ACL通过[schema?permissions]来构成权限列表,schema代表采用的某种权限机制,id代表允许访问的用户,permissions代表权限组合字符串
schma
world:world下只有一个id,即只有一个用户,也就是anyone,那么组合的写法就是world:anyone:[permissions]
auth:代表认证登录,需要注册用户有权限就可以,形式为auth:user:password:[permissions]
digest:需要对密码加密才能访问,组合形式为digest:username:BASE64(SHA1(password)):[permissions]
ip:当设置为ip指定的ip地址,此时限制ip进行访问,比如ip:192.168.1.1:[permissions]
super:代表超级管理员,拥有所有的权限
注意:auth与digest的区别就是,前者明文,后者密文,setAcl /zj auth:lee:lee:cdrwa与setAcl /zj digest:lee:BASE64(SHA1(password)):cdrwa是等价的,在通过addauth digest lee:lee后都能操作指定节点的权限
permissions
权限字符串缩写crdwa
create:创建子节点
read:获取节点/子节点
write:设置节点数据
delete:删除子节点
admin:设置权限
ACL命令行学习
world:anyone:cdrwa
[zk: localhost:2181(CONNECTED) 14] getAcl /zj/node1
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 16] setAcl /zj/node1 world:anyone:cdr
cZxid = 0x33
ctime = Thu Apr 19 18:04:39 CST 2018
mZxid = 0x34
mtime = Thu Apr 19 18:04:52 CST 2018
pZxid = 0x33
cversion = 0
dataVersion = 1
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 17] getAcl /zj/node1
'world,'anyone
: cdr
[zk: localhost:2181(CONNECTED) 18] set /zj/node1 123
Authentication is not valid : /zj/node1
[zk: localhost:2181(CONNECTED) 19] create /zj/node1/haha 123
Created /zj/node1/haha
[zk: localhost:2181(CONNECTED) 20] get /zj/node1/haha
123
cZxid = 0x37
ctime = Thu Apr 19 18:56:57 CST 2018
mZxid = 0x37
mtime = Thu Apr 19 18:56:57 CST 2018
pZxid = 0x37
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 21] delete /zj/node1/haha
[zk: localhost:2181(CONNECTED) 18] set /zj/node1 123
Authentication is not valid : /zj/node1
[zk: localhost:2181(CONNECTED) 19] create /zj/node1/haha 123
Created /zj/node1/haha
[zk: localhost:2181(CONNECTED) 20] get /zj/node1/haha
123
cZxid = 0x37
ctime = Thu Apr 19 18:56:57 CST 2018
mZxid = 0x37
mtime = Thu Apr 19 18:56:57 CST 2018
pZxid = 0x37
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 21] delete /zj/node1/haha
[zk: localhost:21
auth:user:password:darwa
// 此时还没有添加用户
[zk: localhost:2181(CONNECTED) 12] setAcl /zj/node auth:zj:zj:cdrwa
Acl is not valid : /zj/node
// 添加用户
[zk: localhost:2181(CONNECTED) 13] addauth digest zj:zj
[zk: localhost:2181(CONNECTED) 14] setAcl /zj/node auth:zj:zj:cdrwa
cZxid = 0x43
ctime = Thu Apr 19 19:07:11 CST 2018
mZxid = 0x43
mtime = Thu Apr 19 19:07:11 CST 2018
pZxid = 0x43
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 15] getAcl /zj/node
'digest,'zj:4l/wfik0LF35uwJhTfT/JE8qzWM=
: cdrwa
[zk: localhost:2181(CONNECTED) 16] setAcl /zj/node auth:zj1:zj1:cdrwa
cZxid = 0x43
ctime = Thu Apr 19 19:07:11 CST 2018
mZxid = 0x43
mtime = Thu Apr 19 19:07:11 CST 2018
pZxid = 0x43
cversion = 0
dataVersion = 0
aclVersion = 2
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 17] getAcl /zj/node
'digest,'zj:4l/wfik0LF35uwJhTfT/JE8qzWM=
: cdrwa
// 此处4l/wfik0LF35uwJhTfT/JE8qzWM=是相同的,因为auth只取第一次的用户名和密码,所以后面可以使用如下命令
[zk: localhost:2181(CONNECTED) 18] setAcl /zj/node auth:::cdrwa
cZxid = 0x43
ctime = Thu Apr 19 19:07:11 CST 2018
mZxid = 0x43
mtime = Thu Apr 19 19:07:11 CST 2018
pZxid = 0x43
cversion = 0
dataVersion = 0
aclVersion = 3
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 19] getAcl /zj/node
'digest,'zj:4l/wfik0LF35uwJhTfT/JE8qzWM=
: cdrwa
digest:user:BASE64(SHA1(pwd)):cdrwa
addauth digest user:pwd
addauth digest zj:zj添加用户
ip
setAcl /zj/test ip:192.168.0.1:cdrwa
super
修改zkServer.sh增加super管理员,然后重启zkServer.sh
nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "-Dzookeeper.DigestAuthenticationProvider.superDigest=zj:4l/wfik0LF35uwJhTfT/JE8qzWM=" \
使用命令addauth digest zj:zj登录即可,这样,一些不能访问的目录就可以访问了
ACL常用使用场景
开发/测试环境分离,开发者无权操作测试库的节点,只能看
生产环境上控制指定ip的服务可以访问相关节点,防止混乱
zookeeper四字命令Four Letter Words
zookeeper可以通过它自身提供的简写命令来和服务器进行交互
需要使用到nc命令,安装yum install nc
echo [commond] | nc [ip] [port]
stat
查看zookeeper的状态信息,以及是否mode
ruok
查看当前zkserver是否启动,返回imok
dump
列出未经处理的会话和临时节点
conf
查看服务器配置
cons
展示连接到服务器的客户端信息
envi
环境变量
mntr
监控zookeeper健康信息
wchs
展示watch信息
wchc wchp
session与watch及path与watch信息
但是需要进行一下配置,在zoo.cfg在最后一行添加4lw.commands.whitelist=*,然后重启