目前zookeeper的版本是3.6.0,同时增加了几个新特性,同时拥抱了Prometheus.
如果你还对zookeeper不了解的话,建议你认真地阅读这篇文章,我想你会有不少的收获。
zookeeper的特性
/usr/local/jdk
/usr/local/zookeeper
export JAVA_HOME=/usr/local/jdk
export ZOOKEEPER_HOME=/usr/local/zookeeper
export CLASSPATH=.:%JAVA_HOME%/lib/dt.jar:%JAVA_HOME%/lib/tool.jar
#export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$ZOOKEEPER_HOME/bin:$JAVA_HOME/bin
tickTime: ZooKeeper使用的基本时间单位(毫秒)。它用于做心跳,并且最小会话超时将是tickTime的两倍
initLimit:用于集群,允许从节点连接并同步到master节点的初始化连接时间,以tickTime的倍数来表示
syncLimit:用于集群,master主节点与从节点之间发送消息,请求和答应时间长度(心跳机制)
dataDir: 存储内存数据库快照的位置,存储事务日志的更新。
dataLogDir: 可以不配置,如果不配置的话就默认存储在数据目录同级目录下
clientPort: 连接服务器的端口,默认端口是2181
# zookeeper3.6.0集成了prometheus
metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
metricsProvider.httpPort=7000
metricsProvider.exportJvmInfo=true
zkServer.sh --config $ZOOKEEPER_HOME/config start/stop/status/restart
[zk: localhost:2181(CONNECTED) 9] get /zookeeper
# 这里是空值
cZxid = 0x0 # 节点时候zookeeper分配的一个ID
ctime = Wed Dec 31 19:00:00 EST 1969 # 节点创建的时间
mZxid = 0x0 #节点修改后的ID
mtime = Wed Dec 31 19:00:00 EST 1969 # 节点被修改的时间
pZxid = 0x0 # 当前节点子节点的ID
cversion = -1 # 当前子节点的版本号
dataVersion = 0 # 当前节点的数据版本号,修改会自加1
aclVersion = 0 # 当前权限版本,修改会自加1
ephemeralOwner = 0x0 #
dataLength = 0
numChildren = 1 # 子节点的数量
create [-s] [-e] path data acl
# 创建一个节点
[zk: localhost:2181(CONNECTED) 14] create /hanbao hanbao
Created /hanbao
[zk: localhost:2181(CONNECTED) 15] get /hanbao
hanbao
# 创建一个临时的节点
[zk: localhost:2181(CONNECTED) 16] create -e /hanbao/hanbao1 hanbao1
Created /hanbao/hanbao1
[zk: localhost:2181(CONNECTED) 17] get /hanbao/hanbao1
hanbao1
...
ephemeralOwner = 0x10000278d900001 # 是一个临时的节点
...
[zk: localhost:2181(CONNECTED) 18] get /hanbao
hanbao
...
numChildren = 1 # 有一个子节点
# 断开当前的session之后,等到心跳的时间过后。你会发现之前创建的临时节点已经没有了
[zk: localhost:2181(CONNECTED) 0] ls /hanbao # 尚在心跳期间
[hanbao1]
[zk: localhost:2181(CONNECTED) 1] get /hanbao
hanbao
...
[zk: localhost:2181(CONNECTED) 3] ls /hanbao
[]
# 创建有序节点数据
[zk: localhost:2181(CONNECTED) 6] create -s /hanbao/hanbao2 seq
Created /hanbao/hanbao20000000001
[zk: localhost:2181(CONNECTED) 7] create -s /hanbao/hanbao2 seq
Created /hanbao/hanbao20000000002
[zk: localhost:2181(CONNECTED) 8] create -s /hanbao/hanbao2 seq
Created /hanbao/hanbao20000000003
[zk: localhost:2181(CONNECTED) 9] ls /hanbao
[hanbao20000000003, hanbao20000000001, hanbao20000000002]
# 修改数据,同时我们使用乐观锁的情况下更新数据,在设置新的值的时候,我们指定在哪个版本的基础上进行设置数据,当我们在修改某一版本数据的时候如果还有人继续的修改此数据,就会有错误的产生
[zk: localhost:2181(CONNECTED) 29] set /hanbao30000000013 32 1 #同时会返回操作后的数据的元数据
...
dataVersion = 2
...
delete /hanbao #如果当前的节点下面存在其他的子节点。那么就会报错
ls /hanbao
delte /hanbao/hanbao20000000003
stat /test watch # 创建一个队/test的监控事件
[zk: localhost:2181(CONNECTED) 45] stat /test watch
Node does not exist: /test
[zk: localhost:2181(CONNECTED) 46] create /test data
WATCHER::
WatchedEvent state:SyncConnected type:NodeCreated path:/test
Created /test
[zk: localhost:2181(CONNECTED) 49] get /test/test1 watch
data1
cZxid = 0xbf
ctime = Wed Jul 03 23:23:51 EDT 2019
mZxid = 0xbf
mtime = Wed Jul 03 23:23:51 EDT 2019
pZxid = 0xbf
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 50] set /test/test1 789
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/test/test1
cZxid = 0xbf
ctime = Wed Jul 03 23:23:51 EDT 2019
mZxid = 0xc0
mtime = Wed Jul 03 23:26:09 EDT 2019
pZxid = 0xbf
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
常见的事件类型:
注意这些事件一旦被触发了,就消失了,再次更新和删除数据的时候就不会触发watcher的事件了
zk是通过schema:id:permissions构成,其中schema表示某种权限机制,id表示的是允许用户访问的ID,permission是权限组合的字符串
auth与digest的区别就是前者是输入的明文密码,后者输入的是密文密码。如
setAcl /test auth:cloudnative:ecosystem:cdrwa
||
setAcl /test digest:cloudnative:BASE64(SHA1(ecosystem)):cdrwa
在通过addauth digest cloudnative:ecosystem后都能操作指定节点的权限
一些案例
[zk: localhost:2181(CONNECTED) 12] addauth digest test:test
[zk: localhost:2181(CONNECTED) 13] setAcl /home/suoper auth:test:test:cdrwa
Node does not exist: /home/suoper
[zk: localhost:2181(CONNECTED) 14] create /home/suoper suoperdata
Node does not exist: /home/suoper
[zk: localhost:2181(CONNECTED) 15] create /home/ homedata
Command failed: java.lang.IllegalArgumentException: Path must not end with / character
[zk: localhost:2181(CONNECTED) 16] create /home homedata
Created /home
[zk: localhost:2181(CONNECTED) 17] create /home/suoper suoperdata
Created /home/suoper
[zk: localhost:2181(CONNECTED) 18] setAcl /home/suoper auth:test:test:cdrwa
...
aclVersion = 1
[zk: localhost:2181(CONNECTED) 19] getAcl /home/suoper
'digest,'test:V28q/NynI4JI3Rk54h0r8O5kMug=
: cdrwa
当我们重新设置授权之后其密码是不会变化的
[zk: localhost:2181(CONNECTED) 21] setAcl /home/suoper auth:jack:jack:cdrwa
...
aclVersion = 2
[zk: localhost:2181(CONNECTED) 22] getAcl /home/suoper
'digest,'test:V28q/NynI4JI3Rk54h0r8O5kMug=
: cdrwa
[zk: localhost:2181(CONNECTED) 23] setAcl /home/suoper auth:jack::cdrwa
...
aclVersion = 3
[zk: localhost:2181(CONNECTED) 24] getAcl /home/suoper
'digest,'test:V28q/NynI4JI3Rk54h0r8O5kMug=
: cdrwa
digest
[zk: localhost:2181(CONNECTED) 2] create /home/zookeeper data
Created /home/zookeeper
[zk: localhost:2181(CONNECTED) 3] setAcl /home/zookeeper digest:test:V28q/NynI4JI3Rk54h0r8O5kMug=:crwa
...
aclVersion = 1
[zk: localhost:2181(CONNECTED) 4] getAcl /home/zookeeper
Authentication is not valid : /home/zookeeper
[zk: localhost:2181(CONNECTED) 5] addauth digest test:test
[zk: localhost:2181(CONNECTED) 6] getAcl /home/zookeeper
'digest,'test:V28q/NynI4JI3Rk54h0r8O5kMug=
: crwa
ip
[zk: localhost:2181(CONNECTED) 8] create /names data
Created /names
[zk: localhost:2181(CONNECTED) 9] create /names/cloudnative namedata
Created /names/cloudnative
[zk: localhost:2181(CONNECTED) 10] setAcl /names/cloudnative ip:192.168.0.101:crwad
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 8
numChildren = 0
[zk: localhost:2181(CONNECTED) 11] getAcl /names/cloudnative
Authentication is not valid : /names/cloudnative
nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "-Dzookeeper.DigestAuthenticationProvider.suoperDigest=test:V28q/NynI4JI3Rk54h0r8O5kMug=" \
-cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
以上的 DigestAuthenticationProvider
在源码中有一个这样的包名称,包含着一个suoperDigest加密的方法
root@99-129:/usr/local/zookeeper# bin/zkServer.sh --config conf restart
ZooKeeper JMX enabled by default
Using config: conf/zoo.cfg
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
export ZK_CLASSPATH=/etc/zookeeper/conf/:/usr/hdp/current/zookeeper-server/lib/*:/usr/hdp/current/zookeeper-server/*
java -cp $ZK_CLASSPATH org.apache.zookeeper.server.auth.DigestAuthenticationProvider super:super123
OUTPUT:
super:super123->super:UdxDQl4f9v5oITwcAsO9bmWgHSI=
root@99-129:/usr/local/zookeeper# echo stat | nc 192.168.99.129 2181 #注意需要在配置文件中开启四字命令
Zookeeper version: 3.6.0--b4c89dc7f6083829e18fae6e446907ae0b1f22d7, built on 02/25/2020 14:38 GMT
Clients:
/192.168.99.129:40650[0](queued=0,recved=1,sent=0)
Latency min/avg/max: 0/0.0/0
Received: 1
Sent: 0
Connections: 1
Outstanding: 0
Zxid: 0x400000000
Mode: follower
Node count: 5
# arok = are you ok? imok = 😀
# ~# echo ruok | nc 192.168.99.129 2181
imok# ~#
[zk: localhost:2181(CONNECTED) 6] create /test1 data
Created /test1
[zk: localhost:2181(CONNECTED) 7] create -e /test1/testtmp da
Created /test1/testtmp
# ~# echo dump | nc 192.168.99.129 2181
SessionTracker dump:
Session Sets (3):
0 expire at Thu Jan 01 06:41:18 EST 1970:
0 expire at Thu Jan 01 06:41:28 EST 1970:
1 expire at Thu Jan 01 06:41:36 EST 1970:
0x100027515f30000
ephemeral nodes dump:
Sessions with Ephemerals (1):
0x100027515f30000:
/test1/testtmp
# ~# echo config | nc 192.168.99.129 2181
clientPort=2181
dataDir=/root/workspace/zookeeper/version-2
dataLogDir=/var/log/zookeeper/version-2
tickTime=2000
maxClientCnxns=60
minSessionTimeout=4000
maxSessionTimeout=40000
serverId=0
# ~# echo cons | nc 192.168.99.129 2181
/192.168.99.129:58856[0](queued=0,recved=1,sent=0)
/0:0:0:0:0:0:0:1:56124[1](queued=0,recved=93,sent=93,sid=0x100027515f30000,lop=PING,est=1562248442123,to=30000,lcxid=0x7,lzxid=0xe5,lresp=42154935,llat=1,minlat=0,avglat=0,maxlat=6)
# ~# echo envi | nc 192.168.99.129 2181
Environment:
...
# ~# echo mntr | nc 192.168.99.129 2181 # 与遗忘的不同的是,会显示metrics的那些指标数据信息
zk_version 3.4.14-4c25d480e66aadd371de8bd2fd8da255ac140bcf, built on 03/06/2019 16:18 GMT
zk_avg_latency 0
zk_max_latency 6
zk_min_latency 0
zk_packets_received 109
zk_packets_sent 108
zk_num_alive_connections 2
zk_outstanding_requests 0
zk_server_state standalone
zk_znode_count 144
zk_watch_count 0
zk_ephemerals_count 1
zk_approximate_data_size 10282
zk_open_file_descriptor_count 28
zk_max_file_descriptor_count 1048576
zk_fsync_threshold_exceed_count 0
# ~# echo wchs | nc 192.168.99.129 2181
0 connections watching 0 paths
Total watches:0
[zk: localhost:2181(CONNECTED) 9] get /zookeeper watch
cZxid = 0x0
ctime = Wed Dec 31 19:00:00 EST 1969
mZxid = 0x0
mtime = Wed Dec 31 19:00:00 EST 1969
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
# ~# echo wchs | nc 192.168.99.129 2181
1 connections watching 1 paths
Total watches:1
# ~# echo wchc | nc 192.168.99.129 2181
wchc is not executed because it is not in the whitelist.
# ~# echo wchp | nc 192.168.99.129 2181
wchp is not executed because it is not in the whitelist.
# echo wchp | nc 192.168.99.129 2181
/zookeeper
0x100027515f30000
# echo wchs | nc 192.168.99.129 2181
1 connections watching 1 paths
Total watches:1
# echo wchc | nc 192.168.99.129 2181
0x100027515f30000
/zookeeper
metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
metricsProvider.httpPort=7000
metricsProvider.exportJvmInfo=true
metrics的端口为7000,路径为:/metircs
root@99-131:/usr/local/apache-zookeeper-3.6.0-bin/logs# curl -I http://192.168.99.129:7000/metrics
HTTP/1.1 200 OK
Date: Mon, 20 Apr 2020 07:35:16 GMT
Content-Type: text/plain; version=0.0.4; charset=utf-8
Content-Length: 29328
Server: Jetty(9.4.24.v20191120)
./zkServer.sh status
# cat zoo.cfg | egrep -v '^#'
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/usr/local/zk1/dataDir
dataLogDir=/usr/local/zk1/dataLogDir
clientPort=2181 # zk1实例运行的端口
4lw.commands.whitelist=*
server.1=192.168.99.129:2888:3888
server.2=192.168.99.129:2889:3889
server.3=192.168.99.129:2890:3890
cd /usr/local/zk1/dataDir
echo "1" > ./myid
/usr/local/zk1/bin/zkServer.sh start
/usr/local/zk2/bin/zkServer.sh start
/usr/local/zk3/bin/zkServer.sh start
1,和单节点上部署zk节点一样,但是有个地方值得注意的是,因为我们现在在多主机节点上部署zk集群,所以不存在多实例运行端口冲突的问题,因此建议将多节点上的zk服务的端口都设置为2181,数据同步端口设置为2888,集群心跳监测端口设置为3888
3.6+
3.4+