本文将分享一些zookeeper在日常使用中一些维护经验。
zookeeper清理快照
脚本或者命令清理
zookeeper长时间运行,快照逐渐增多可能造成服务器磁盘被占满的情况,但我们不能贸然用rm命令删除快照文件,如果直接删完会导致丢失好多数据,所以我们需要设置相关参数,并使用一些优雅的命令来删除文件,zookeeper自带的脚本zkCleanup.sh。
[root@k8s-m1 bin]# ./zkCleanup.sh
Usage:
PurgeTxnLog dataLogDir [snapDir] -n count
dataLogDir -- path to the txn log directory
snapDir -- path to the snapshot directory
count -- the number of old snaps/logs you want to keep, value should be greater than or equal to 3
2023-09-01 14:44:34,660 [myid:] - ERROR [main:ServiceUtils@48] - Exiting JVM with code 1
如:保留最近20个snap文件
[root@k8s-m1 bin]# ./zkCleanup.sh -n 20
使用自带的这个脚本可以较好的删除,当然我们也可以使用一些linux命令删除n天前的数据,注意自己实际环境中的目录设置。
[root@k8s-m1 bin]# find /zookeeperData/version-2/ -name "snap*" -mtime +10 | xargs rm -f
[root@k8s-m1 bin]# find /zookeeperDataLog/version-2/ -name "log*" -mtime +10 | xargs rm -f
[root@k8s-m1 bin]# find /opt/apache-zookeeper-3.7.1-bin/logs -name "zookeeper.log.*" -mtime +10 | xargs rm –f
配置自动清理日志
从3.4.0开始,会自动清理日志了,所以这个通常不用配置。
配置autopurge.snapRetainCount和autopurge.purgeInterval参数。
保留的snapshop的数量,默认是3个,最小也是3。
autopurge.snapRetainCount=3
autopurge.purgeInterval=1
3.4.0之前的版本可以通过zookeeper的配置自行对snap进行管理。如下这三个参数分别表示一个小时清理一次,log的大小(单位是kb)和快照的数量。
另外要注意的是,zookeeper重启会自动清除zookeeper.out日志,所以如果出错要注意先备份这个文件。
watches数量多的问题
dubbo对于每个结点都会watch,导致watch数很多,随便都几千个。用wchs,wchc,wchp这些命令可以查看watches的信息,包括总数,每条路径上的watch的数量,每个client的。
[root@k8s-m1 logs]# echo wchs |nc localhost 2181
查找不能成功启动原因
zookeeper会有很多原因启动不成功,可以通过以下命令来查看启动时报的是什么异常,同时也可以查看运行过程中的异常。
[root@k8s-m1 apache-zookeeper-3.7.1-bin]# ./bin/zkServer.sh start-foreground
还可以通过下面命令查看zookeeper启动的各个参数,包括java路径等,也可以便于查找问题。
[root@k8s-m1 apache-zookeeper-3.7.1-bin]# ./bin/zkServer.sh print-cmd
配置zookeeper.out
的位置及log4j
滚动日志输出
有时候,zookeeper.out这个文件很大。根据zkServer.sh的代码,这个zookeeper.out实际上是nohup的输出。而nohup的输出实际上是stdout和stderr的输出,所以还是zookeepe本身的日志配置的问题,而这样输出路径和大小没法控制,因为日志文件没有轮转。所以需要修改日志输出方式。
查看bin/zkServer.sh和conf/log4j.properties这两个文件,发现zookeeper其实是有日志相关的输出的配置,只要定义相关的变量就可以了。
主要是ZOO_LOG_DIR和ZOO_LOG4J_PROP这两个环境变量,
zkServer.sh里的:
if [ ! -w "$ZOO_LOG_DIR" ] ; then
mkdir -p "$ZOO_LOG_DIR"
fi
ZOO_LOG_FILE=zookeeper-$USER-server-$HOSTNAME.log
_ZOO_DAEMON_OUT="$ZOO_LOG_DIR/zookeeper-$USER-server-$HOSTNAME.out"
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 1
fi
fi
nohup "$JAVA" $ZOO_DATADIR_AUTOCREATE "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" \
"-Dzookeeper.log.file=${ZOO_LOG_FILE}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" \
-XX:+HeapDumpOnOutOfMemoryError -XX:OnOutOfMemoryError='kill -9 %p' \
-cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &
而zkServer.sh会加载zkEnv.sh。因此,其实修改下bin/zkEnv.sh里面的ZOO_LOG_DIR变量就可以了。而ZOO_LOG4J_PROP指定INFO,ROLLINGFILE日志的APPENDER。
if [ "x${ZOO_LOG_DIR}" = "x" ]
then
ZOO_LOG_DIR="$ZOOKEEPER_PREFIX/logs"
fi
if [ "x${ZOO_LOG4J_PROP}" = "x" ]
then
#ZOO_LOG4J_PROP="INFO,CONSOLE"
#ZOO_LOG4J_PROP="INFO,DailyROLLINGFILE"
ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
fi
#需要将CONSOLE改成ROLLINGFILE
log4j.properties里的:zookeeper.root.logger的值与前一个文件的ZOO_LOG4J_PROP 保持一致(注意保持一致非常重要,否则zookeeper不能正常启动),该日志配置是以日志文件大小轮转的,如果想要按照天轮转,可以修改为DaliyRollingFileAppender。
[root@k8s-m1 bin]# vim /opt/apache-zookeeper-3.7.1-bin/conf/log4j.properties
zookeeper.root.logger=INFO, ROLLINGFILE
#zookeeper.root.logger=INFO, DailyROLLINGFILE
.......
# Add ROLLINGFILE to rootLogger to get log file output
#
log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
#log4j.appender.ROLLINGFILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold}
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
log4j.appender.ROLLINGFILE.MaxFileSize=${zookeeper.log.maxfilesize}
log4j.appender.ROLLINGFILE.MaxBackupIndex=${zookeeper.log.maxbackupindex}
log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
还可以修改下conf/log4j.properties,设置滚动日志最多为10个:
# Max log file size of 10MB
log4j.appender.RFAAUDIT.MaxFileSize=10MB
log4j.appender.RFAAUDIT.MaxBackupIndex=10
Too many connections from 错误
这个错误是因为同一个IP的zookeeper socket 连接数大于60了。zookeeper server默认限制每个IP最多60个连接。
需要修改修改zoo.cfg中的如下配置:
maxClientCnxns=1000
This ZooKeeper instance is not currently serving requests 的错误提示
当集群里的结点只剩下一台,或者不足半数时,就会出现这个错误提示。
通常在,只启动第一台zookeeper时会报这个错误。
在zookeeper server的日志里,会有类似的日志:
Exception causing close of session 0x0 due to java.io.IOException: ZooKeeperServer not running
管理工具
Zookeeper官方自带的管理员工具
官方的命令行工具可以胜任绝大部分工作了。
部分操作可以参考https://blog.csdn.net/margu_168/article/details/132606402
zktop
python写的小工具
https://github.com/phunt/zktop
PrettyZoo
PrettyZoo是一款Java写的高颜值ZooKeeper客户端桌面应用,颜值非常高,支持Mac / Windows / Linux。
下载地址: https://github.com/vran-dev/PrettyZoo/releases
具备如下功能:
- 可同时管理多个 zookeeper 连接
- 节点数据实时同步
- 支持 ACL 配置
- 支持 SSH Tunnel 连接
- 支持配置导入、导出
- 支持节点增删改查操作
- 支持 command line 操作模式
- 支持节点数据格式化 JSON、XML
- 支持节点数据高亮(JSON、XML、Properties)
更多管理工具请自行测试使用。
更多关于zookeeper的知识分享,请前往博客主页。编写过程中,能力有限难免出现差错,敬请指正