11.2.6 常见部署问题与处理

本节聚焦 ZooKeeper 部署与集群搭建中的高频问题、现象判断与处理步骤,覆盖配置、启动、通信、存储与运行时环境等维度,帮助快速恢复集群可用性并形成可复用的排障流程。

文章图片

1. 配置与启动失败类问题#

1.1 配置文件解析错误#

现象
- 启动报错:Error processing configInvalid config, exiting
- 进程启动后立即退出

常见原因
- zoo.cfg 语法错误(空格/缩进/非法字符)
- dataDirdataLogDir 不存在或无权限
- server.X 格式错误、缺少 :2888:3888

处理步骤(示例)

# 1) 定位错误配置行
grep -n "server\|dataDir\|dataLogDir" /opt/zookeeper/conf/zoo.cfg

# 2) 校验目录存在与权限
ls -ld /data/zk /data/zklog
sudo chown -R zk:zk /data/zk /data/zklog

# 3) 校验 myid 与 server.X 一致
cat /data/zk/myid
grep -n "server\.1\|server\.2\|server\.3" /opt/zookeeper/conf/zoo.cfg

# 4) 启动前试探状态(非运行会提示未启动)
/opt/zookeeper/bin/zkServer.sh status

正确配置示例

# /opt/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zk
dataLogDir=/data/zklog
clientPort=2181
server.1=10.0.0.11:2888:3888
server.2=10.0.0.12:2888:3888
server.3=10.0.0.13:2888:3888

1.2 JVM 启动参数异常#

现象
- 启动报错:Could not reserve enough space for object heap
- 启动后 OOM 或 GC 频繁

常见原因
- JAVA_HOME 指向错误
- Xmx 设置超过物理内存

处理步骤(示例)

# 1) 检查 JAVA_HOME
echo "$JAVA_HOME"
java -version

# 2) 调整 JVM 参数(以 1G 内存为例)
cat >/opt/zookeeper/conf/java.env <<'EOF'
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk
export JVMFLAGS="-Xms512m -Xmx512m -XX:+UseG1GC"
EOF

# 3) 重新启动
/opt/zookeeper/bin/zkServer.sh restart

命令解释
- java.env:ZooKeeper 启动脚本会读取该文件中的 JVM 参数
- -Xms/-Xmx:设置最小/最大堆内存


2. 集群不成形或选举异常#

2.1 集群无法选主#

现象
- 所有节点均为 LOOKING
- 选举持续超时

常见原因
- myidserver.X 不匹配
- 端口被防火墙/安全组阻断
- 时间偏差过大,选举超时

处理步骤(示例)

# 1) 校验 myid 文件内容
cat /data/zk/myid  # 预期为 1/2/3 中的某一个

# 2) 端口连通性检查(在每个节点执行)
nc -vz 10.0.0.11 2888
nc -vz 10.0.0.12 2888
nc -vz 10.0.0.13 3888

# 3) 时间同步(以 chrony 为例)
sudo chronyc tracking
sudo chronyc sources -v

快速验收预期

/opt/zookeeper/bin/zkServer.sh status
# 预期输出之一:
# Mode: leader
# Mode: follower

2.2 多节点成为独立单机#

现象
- 多台节点均显示 standalone
- 集群状态无法聚合

常见原因
- server.X 配置缺失或未生效
- 使用了默认配置文件启动

处理步骤(示例)

# 1) 确认启动脚本加载的配置路径
ps -ef | grep zookeeper | grep -v grep

# 2) 校验配置一致性
md5sum /opt/zookeeper/conf/zoo.cfg

3. 端口与网络连通性问题#

3.1 端口占用或冲突#

现象
- 启动失败提示端口占用
- 日志包含 Address already in use

处理步骤(示例)

# 1) 查看端口占用
ss -lntp | grep -E "2181|2888|3888"

# 2) 若冲突,停止占用进程(示例)
sudo kill -9 <PID>

# 3) 放行防火墙(示例)
sudo firewall-cmd --add-port=2181/tcp --permanent
sudo firewall-cmd --add-port=2888/tcp --permanent
sudo firewall-cmd --add-port=3888/tcp --permanent
sudo firewall-cmd --reload

3.2 跨机房或多网卡绑定错误#

现象
- 节点之间无法连接或连接不稳定
- 日志包含 connection refused

处理步骤(示例)

# /opt/zookeeper/conf/zoo.cfg
# 明确内网 IP
server.1=10.0.0.11:2888:3888
server.2=10.0.0.12:2888:3888
server.3=10.0.0.13:2888:3888
quorumListenOnAllIPs=false

4. 数据目录与权限问题#

4.1 dataDir 无法写入#

现象
- 启动日志提示 Permission denied
- 无法创建 log.*snapshot.*

处理步骤(示例)

# 1) 创建目录并授权
sudo mkdir -p /data/zk /data/zklog
sudo chown -R zk:zk /data/zk /data/zklog
sudo chmod 750 /data/zk /data/zklog

# 2) 检查磁盘空间与 inode
df -h /data/zk
df -i /data/zk

4.2 dataLogDir 缺失或不可用#

现象
- 事务日志写入失败
- 频繁的 IOException

处理步骤(示例)

# 1) 指向独立磁盘
sed -i 's|^dataLogDir=.*|dataLogDir=/data/zklog|' /opt/zookeeper/conf/zoo.cfg

# 2) 重新启动
/opt/zookeeper/bin/zkServer.sh restart

5. 版本与兼容性问题#

5.1 JDK 与 ZooKeeper 版本不匹配#

现象
- 启动时报 Unsupported major.minor version
- 运行时异常或性能异常

处理步骤(示例)

# 1) 查看 ZooKeeper 版本
/opt/zookeeper/bin/zkServer.sh version

# 2) 查看 JDK 版本
java -version

# 3) 切换 JAVA_HOME
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk

5.2 配置项版本差异#

现象
- 启动警告未知参数
- 部分节点配置不生效

处理步骤(示例)

# 1) 搜索不支持的配置
grep -n "quorumListenOnAllIPs\|admin.serverPort" /opt/zookeeper/conf/zoo.cfg

# 2) 参考当前版本文档清理配置

6. 日志与排障定位#

6.1 日志级别过高或缺失#

现象
- 无法定位错误
- 日志量过大影响磁盘

处理步骤(示例)

# /opt/zookeeper/conf/log4j.properties
zookeeper.root.logger=INFO, CONSOLE

日志轮转示例

# /etc/logrotate.d/zookeeper
/opt/zookeeper/logs/*.log {
  daily
  rotate 7
  compress
  missingok
  notifempty
  copytruncate
}

6.2 快速诊断命令(带预期)#

# 查看角色
/opt/zookeeper/bin/zkServer.sh status
# 预期:Mode: leader|follower

# 连接测试
echo ruok | nc 127.0.0.1 2181
# 预期:imok

# 端口连通
nc -vz 10.0.0.12 2888
# 预期:succeeded

# 日志定位
tail -n 50 /opt/zookeeper/logs/zookeeper.out

7. 集群验收不通过的处理#

常见问题
- 读写延迟高:检查磁盘 IOPS、GC、网络 RTT。
- 节点频繁重启:关注 OOM、磁盘满、JVM 参数。
- 心跳超时:调整 tickTimeinitLimitsyncLimit

验收示例(写读自检)

# 使用 zkCli 进行写读
/opt/zookeeper/bin/zkCli.sh <<'EOF'
create /health "ok"
get /health
EOF
# 预期:cZxid... data: ok

建议处理流程
1. 从日志确认是否为启动阶段错误。
2. 验证端口与 myid/server.X 一致性。
3. 逐步扩容验证:先 1 节点,再 3 节点,最后 5 节点。
4. 记录配置、日志与原因,形成标准化故障案例库。


8. 部署问题处理清单(最小闭环)#

  • 配置一致性:zoo.cfg + myid + 端口
  • 用户与权限:专用用户、目录可写
  • 网络与端口:2181/2888/3888 连通
  • 版本统一:JDK 与 ZooKeeper 版本一致
  • 磁盘与日志:数据目录可用、日志可追踪

练习#

  1. 人为将 server.2 的端口写成 server.2=10.0.0.12:2888,观察启动日志并修复。
  2. dataDir 权限改为只读,复现 Permission denied 并恢复。
  3. 使用 echo ruok | nc 检查节点健康,记录 imok 与失败时的差异日志。