11.8.5 日志分析与诊断工具使用

日志分析与诊断工具使用#

原理草图:日志与诊断数据流#

文章图片

日志体系与关键文件(含路径示例)#

  • 主日志/var/log/zookeeper/zookeeper.logzookeeper.out
  • 事务日志dataDirlog.*
  • 快照日志dataDirsnapshot.*
  • JVM日志/var/log/zookeeper/gc.loghs_err_pid*.log

安装与基础配置(启用可分析日志)#

# 1) 安装(以二进制安装为例)
tar -zxvf apache-zookeeper-3.8.3-bin.tar.gz -C /opt/
ln -s /opt/apache-zookeeper-3.8.3-bin /opt/zookeeper

# 2) 配置日志目录
mkdir -p /var/log/zookeeper /data/zk
chown -R zk:zk /var/log/zookeeper /data/zk

# 3) 配置 zoo.cfg(示例)
cat >/opt/zookeeper/conf/zoo.cfg <<'EOF'
tickTime=2000
dataDir=/data/zk
clientPort=2181
autopurge.snapRetainCount=10
autopurge.purgeInterval=1
# 允许四字命令(3.5+推荐显式开启)
4lw.commands.whitelist=ruok,stat,mntr,cons,dump
EOF

# 4) 配置 log4j(示例)
cat >/opt/zookeeper/conf/log4j.properties <<'EOF'
zookeeper.root.logger=INFO, CONSOLE, ROLLINGFILE
zookeeper.log.dir=/var/log/zookeeper
zookeeper.log.file=zookeeper.log
log4j.rootLogger=${zookeeper.root.logger}
log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
log4j.appender.ROLLINGFILE.MaxFileSize=100MB
log4j.appender.ROLLINGFILE.MaxBackupIndex=10
log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} %-5p [%t:%C{1}@%L] - %m%n
EOF

# 5) 启动并检查日志生成
/opt/zookeeper/bin/zkServer.sh start
tail -f /var/log/zookeeper/zookeeper.log

日志级别与定位方法(命令示例)#

# 按时间定位异常窗口(假设故障时间 10:05)
grep "2024-07-01 10:0" /var/log/zookeeper/zookeeper.log

# 统计 ERROR/FATAL
egrep -n "ERROR|FATAL" /var/log/zookeeper/zookeeper.log | head -20

# 按关键字定位选举/会话异常
egrep -n "LOOKING|LEADING|FOLLOWING|Session expired|Closing session" /var/log/zookeeper/zookeeper.log

常见关键日志模式(对照说明)#

  • 会话超时Session expiredClosing session
  • 选举异常LOOKINGFOLLOWINGLEADING 反复切换
  • 磁盘问题No space left on devicefsync 失败
  • 请求积压OutstandingRequestsToo many connections

诊断工具安装与使用#

四字命令(诊断入口)#

# 允许四字命令后,可用 nc 调用
echo mntr | nc 127.0.0.1 2181
echo stat | nc 127.0.0.1 2181
echo cons | nc 127.0.0.1 2181

# 结果示例(节选)
# zk_server_state  leader
# zk_num_alive_connections  128
# zk_outstanding_requests   3

命令解释
- mntr:输出核心监控指标(延迟、连接数、请求积压)
- stat:角色、模式与连接概览
- cons:连接详情(IP、会话、队列)

JVM 诊断命令(线程/堆)#

# 找到 ZooKeeper 进程
ps -ef | grep QuorumPeerMain | grep -v grep

# JVM 线程栈(排查阻塞/死锁)
jstack <PID> > /tmp/zk.jstack.txt

# 堆与 GC 观察
jstat -gcutil <PID> 1000 10

# 堆快照(需磁盘空间)
jmap -dump:live,format=b,file=/tmp/zk.hprof <PID>

系统诊断命令(IO/CPU)#

# 观察 IO 延迟与负载
iostat -x 1 5
vmstat 1 5
pidstat -d -p <PID> 1 5

典型问题排查流程(包含示例)#

案例1:频繁会话断开#

# 1) 找到断开时间
egrep -n "Session expired|Closing session" /var/log/zookeeper/zookeeper.log | tail -20

# 2) 查看连接数与会话
echo cons | nc 127.0.0.1 2181 | head -10

# 3) 检查网络抖动(示例)
ping -c 10 zk-client-host

可能原因:网络抖动、客户端超时过短、tickTime/initLimit/syncLimit 不合理。
处理建议:调整客户端超时时间、检查网络、优化 GC。

案例2:写入延迟高/请求积压#

# 1) 查看请求积压
echo mntr | nc 127.0.0.1 2181 | egrep "outstanding|avg_latency|max_latency"

# 2) 检查日志盘性能
iostat -x 1 5 | egrep "Device|sda|sdb"

# 3) 检查事务日志与快照是否同盘
grep dataDir /opt/zookeeper/conf/zoo.cfg

可能原因:磁盘 IO 瓶颈、日志与快照同盘、fsync 延迟。
处理建议:分离事务日志与快照盘、提升磁盘性能。

案例3:Leader 频繁变更#

# 1) 查找状态切换
egrep -n "LEADING|FOLLOWING|LOOKING" /var/log/zookeeper/zookeeper.log | tail -50

# 2) 检查 GC 停顿
grep "Full GC" /var/log/zookeeper/gc.log | tail -10

可能原因:GC 停顿、时钟漂移、网络抖动。
处理建议:优化 JVM 堆与 GC,NTP 校时。

日志保留与轮转(完整可执行示例)#

# /etc/logrotate.d/zookeeper
cat >/etc/logrotate.d/zookeeper <<'EOF'
/var/log/zookeeper/*.log {
  daily
  rotate 14
  compress
  delaycompress
  missingok
  notifempty
  copytruncate
}
EOF

# 测试轮转
logrotate -f /etc/logrotate.d/zookeeper

排错清单(速查)#

  • 磁盘空间:df -hdu -sh /data/zk
  • 进程状态:/opt/zookeeper/bin/zkServer.sh status
  • 端口:ss -lntp | grep 2181
  • 时钟:timedatectl status

练习#

  1. 使用 mntr 获取 zk_outstanding_requests,并解释数值意义。
  2. 制造一次日志轮转,验证是否产生压缩包。
  3. 在日志中查找 Session expired 并写出定位步骤。
  4. 使用 jstack 抓取线程栈,标出一个可能阻塞的线程。