zookeeper

ZooKeeper的基本使用

zookeeper的常用服务端命令

服务启动命令

sh ${ZOOKEEPER_HOME}/bin/zkServer.sh start

服务停止命令

sh ${ZOOKEEPER_HOME}/bin/zkServer.sh stop

服务重启命令

sh ${ZOOKEEPER_HOME}/bin/zkServer.sh restart

服务状态命令

sh ${ZOOKEEPER_HOME}/bin/zkServer.sh status

连接服务命令

sh ${ZOOKEEPER_HOME}/bin/zkCli.sh -server host:port

zookeeper的常用客户端命令

ls 命令

ls命令用于列出指定ZNode的子节点

create 命令

create命令用于创建指定的ZNode。

get 命令

get命令用于获取指定ZNode的值。

set 命令

set命令用于设置指定ZNode的值。

delete命令

delete命令用于删除指定的ZNode,不能删除子ZNode不为空的ZNode。

rmr 递归删除节点

使用rmr命令可以删除节点以及节点的子节点。

quit 命令

quit用于退出当前科幻。

数据状态信息

cZxid:节点被创建时使用的事务id - 不变
ctime: 节点的创建时间 - 不变
mZxid: 节点最后一次被修改使用的事务id - 改变
mtime:节点最后一次被修改的时间 - 改变
pZxid:子节点id。
cversion:子节点version
dataVersion: 当前节点数据版本号,数据修改一次,版本号增加一。
aclVersion:节点ACL的版本,ACL修改一次,版本号增加一。
ephemeralOwner:临时节点所归属的Session。
dataLength:数据长度。
numChildren:子节点的个数。

zookeeper的四字母命令

命令 描述
conf (New in 3.3.0)输出相关服务配置的详细信息。比如端口、zk数据及日志配置路径、最大连接数,session超时时间、serverId等
cons (New in 3.3.0)列出所有连接到这台服务器的客户端连接/会话的详细信息。包括“接受/发送”的包数量、session id 、操作延迟、最后的操作执行等信息。
crst (New in 3.3.0)重置当前这台服务器所有连接/会话的统计信息
dump 列出未经处理的会话和临时节点(只在leader上有效)
envi 输出关于服务器的环境详细信息(不同于conf命令),比如host.name、java.version、java.home、user.dir=/data/zookeeper-3.4.6/bin之类信息
reqs 列出未经处理的请求
ruok 测试服务是否处于正确状态。如果正常,返回“imok”
srst 重置服务器的统计信息
srvr (New in 3.3.0)输出服务器的详细信息。zk版本、接收/发送包数量、连接数、模式(leader/follower)、节点总数。
stat 输出关于性能和连接的客户端的列表
wchs 列出Server的watch的详细信息
wchc 通过Session列出服务器watch的详细信息,他的输出是一个与watch相关的会话的列表。小心使用。
wchp 通过路径列出服务器watch的详细信息。它输出一个与Session相关的路径。小心使用。
mntr (New in 3.4.0)列出集群的健康状态。包括“接受/发送”的包数量、操作延迟、当前服务模式(leader/follower)、节点总数、watch总数、临时节点总数。

如何使用四字命令

1
2
3
4
echo conf | nc host port
如:
echo stat | nc zookeeper.com 2181

比如可以使用stat来查看当前server节点的连接信息,从而找出连接数太多的server。

权限管理

ACL

ACL的特性

ZooKeeper 的权限控制是基于每个 znode 节点的,需要对每个节点设置权限
每个 znode 支持设置多种权限控制方案和多个权限
子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问它的子节点

可控操作

ACL可以控制的具体操作有:

CREATE :(缩写c)可以创建子节点。
DELETE :(缩写d)可以删除子节点。
READ :(缩写r)可以读取节点数据及显示子节点列表。
WRITE :(缩写w)可以设置节点数据。
ADMIN :(缩写a)可以设置节点访问控制列表权限。

控制模式

ACL以如下模式进行ACL控制:

world :只有一个用户:anyone,代表所有人(默认)。
ip :使用IP地址认证。
auth :使用以添加认证的用户认证。
digest :使用“用户名:密码”认证。
sasl:Kerberos的认证方式

设置ACL的命令为setAcl,此命令后面跟的是znode和需要设置的Acl信息,如:setAcl / ip:127.0.0.1:cdwra。其中的Acl信息包含三部分内容:Acl模式:模式信息:具体的权限。
对于world模式的设置为:world:anyone:cdrwa,其中world:anyone是固定的,后面的cdrwa可以根据自己的需求进行设置。对于ip模式的设置为:ip:127.0.0.1:cdwra,ip指定了ACL的模式,模式信息为ip地址,最后是具体的权限。auth模式的设置为: auth:userName:cdrwa,其中auth指定了ACL的模式,userName指定需要使用的认证的用户名,最后是具体的权限,这里的第二部分的userName是指通过addauth userName:password命令在server上通过鉴权用户名,也就是使用server中已经鉴权过的用户的信息进行设置。digest模式的设置为:digest:userName:password:cdwra,digest指定了ACL的模式,userName:password是通过特殊处理的账号和密码(下面会介绍),最后一部分是具体的权限。

通过 setAcl /path digest:userName:password:acl 可以设置 digest类型的ACL。这里的密码是经过SHA1及BASE64处理过的密文,在Shell中如下命令来获取:

1
echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64

对于auth和digest两种方式设置的ACL,需要通过addauth添加认证信息后,才可以操作。

相关命令

与ACL相关的命令包括如下:

getAcl:获取指定ZNode的ACL信息。
setAcl:设置制定ZNode的ACL信息。
addauth: 为当前连接增加认证信息。

Kerberos

ZooKeeper中使用Kerberos可以用来控制三个点:1、Server之间的连接;2、Client与Server之间的连接;3、ZNode的ACL。如果要在ZooKeeper中启用Kerberos,需要进行如下配置:
首先需要在zoo.cfg中增加如下配置:

1
2
3
4
authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
jaasLoginRenew=3600000
kerberos.removeHostFromPrincipal=true
kerberos.removeRealmFromPrincipal=true

在ZooKeeper的配置目录下(/opt/zookeeper/conf)添加环境文件“java.env”,其内容为:

1
export JVMFLAGS="-Djava.security.auth.login.config=/home/zookeeper/zookeeper-3.5.1-alpha/conf/jaas.conf" // 此处指定jaas.conf文件

在ZooKeeper的配置目录下(/opt/zookeeper/conf)添加配置文件“jaas.conf”,其内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Server {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/home/zookeeper/zookeeper-3.5.1-alpha/conf/zookeeper.keytab" // 指定keyTab文件
storeKey=true
useTicketCache=false
principal="zookeeper/zdh-237@ZDH.COM"; // 指定principal文件
};
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="/home/zookeeper/zookeeper-3.5.1-alpha/conf/zookeeper.keytab" // 指定keyTab文件
storeKey=true
useTicketCache=false
principal="zookeeper/zdh-237@ZDH.COM"; // 指定principal文件
};

这里包含了server的和client的,如果不需要client,可以只保留server 的。
另外,开启了Kerberos的ZooKeeper集群是可以通过非Kerberos方式连接的,server会自动降级。

超级管理员角色

默认的ZK Server在启动的时候,是没有超级管理员的权限的,要增加超级管理员的权限,我们可以在zkServer.sh

1
2
3
4
5
6
7
8
9
10
11
12
case $1 in
start)
echo -n "Starting zookeeper ... "
if [ -f "$ZOOPIDFILE" ]; then
if kill -0 `cat "$ZOOPIDFILE"` > /dev/null 2>&1; then
echo $command already running as process `cat "$ZOOPIDFILE"`.
exit 0
fi
fi
nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
#TODO
-cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &

中的“#TODO”位置增加

1
"-Dzookeeper.DigestAuthenticationProvider.superDigest=super:crJlNpw5TWXtn9f8LCsep65WWyg=" \

这样一段配置,那么在连接到这个节点后,使用addauth digest super:password进行鉴权,然后就有超级管理员的权限啦。
超级管理员可以使用的场景设置ACL的账号密码忘记了,或者想要操作由Kerberos管理的的ZNode。

Python 操作zookeeper

首先需要安装 kazoo

1
pip install kazoo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/python
import sys
from kazoo.client import KazooClient,KazooState
zk = KazooClient(
hosts='hadoop2035.rz.momo.com:2182'
,timeout=10.0
)
zk.start()
path = "/databridgemanager_mirror/dataDir/finished"
children = zk.get_children(path);
zk.stop()
zk.close()

问题排查

Session Timeout

在ZooKeeper的使用过程中,经常遇到的一个问题是 Session Timeout,在我们的使用场景中,Kafka的某些节点总是遇到Session Timeout从而导致leader切换。

ZooKeeper的监控