1. 为什么需要Zookeeper集群?

Zookeeper作为分布式系统的"协调员",在微服务架构中扮演着关键角色。我遇到过不少开发者刚开始只部署单节点,结果当这个节点挂掉时,整个系统就瘫痪了。集群部署能带来三大核心优势:

高可用性 是集群最直接的价值。去年我们一个电商项目就吃过亏,大促时单节点Zookeeper宕机,导致所有订单服务无法协调。后来改用三节点集群后,即使一台物理机故障,服务依然能自动切换。

数据一致性 通过ZAB协议保证。我做过一个测试:在五节点集群中随机停掉两个节点,剩余节点仍能保持数据同步。这得益于它的多数派写入机制——只要超过半数节点存活就能正常工作。

负载均衡 在实际生产环境中特别实用。通过客户端连接不同的Zookeeper节点,可以避免单个节点压力过大。我们有个物联网平台,设备连接数突破50万时,三节点集群的CPU负载始终保持在30%以下。

2. 环境准备与规划

2.1 硬件资源建议

根据我的踩坑经验,集群部署前要做好资源规划。下面这个表格是我总结的配置参考:

节点规模 CPU核心 内存 磁盘类型 网络带宽
开发环境 2核 4GB SSD 1Gbps
测试环境 4核 8GB NVMe 2.5Gbps
生产环境 8核+ 16GB+ RAID10 10Gbps

特别提醒: 避免所有节点部署在同一物理机 !有次我们为省事把三个节点放同一台服务器,结果电源故障导致全集群不可用。建议至少跨三个可用区。

2.2 软件依赖安装

先确保所有节点已安装Docker和Docker Compose。这是我验证过的版本组合:

# 检查Docker版本(建议20.10+)
docker --version

# 检查Docker Compose版本(建议v2.2+)
docker compose version

如果尚未安装,可以用这个一键脚本:

# Ubuntu/CentOS通用安装命令
curl -fsSL https://get.docker.com | sh
sudo systemctl enable --now docker
sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

3. 编写docker-compose.yml

3.1 完整配置示例

这是我优化过的三节点配置,直接保存为 docker-compose.yml

version: '3.9'
services:
  zoo1:
    image: zookeeper:3.9.2
    hostname: zoo1
    container_name: zoo1
    ports:
      - "2181:2181"
      - "2888:2888"
      - "3888:3888"
    volumes:
      - ./data/zoo1:/data
      - ./datalog/zoo1:/datalog
      - ./conf/zoo1:/conf
    environment:
      ZOO_MY_ID: 1
      ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
      ZOO_STANDALONE_ENABLED: "false"
    networks:
      - zk_net

  zoo2:
    image: zookeeper:3.9.2
    hostname: zoo2
    container_name: zoo2
    ports:
      - "2182:2181"
      - "2889:2888"
      - "3889:3888"
    volumes:
      - ./data/zoo2:/data
      - ./datalog/zoo2:/datalog
      - ./conf/zoo2:/conf
    environment:
      ZOO_MY_ID: 2
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zoo3:2888:3888;2181
    networks:
      - zk_net

  zoo3:
    image: zookeeper:3.9.2
    hostname: zoo3
    container_name: zoo3
    ports:
      - "2183:2181"
      - "2890:2888"
      - "3890:3888"
    volumes:
      - ./data/zoo3:/data
      - ./datalog/zoo3:/datalog
      - ./conf/zoo3:/conf
    environment:
      ZOO_MY_ID: 3
      ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181
    networks:
      - zk_net

networks:
  zk_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/24

3.2 关键配置解析

端口映射规则

  • 218X:客户端连接端口(X对应节点号)
  • 288X:节点间数据同步端口
  • 388X:选举通信端口

数据持久化

  • /data :存储快照数据
  • /datalog :事务日志(WAL)
  • /conf :自定义配置文件目录

环境变量玄机

  • ZOO_MY_ID 必须唯一且为1-255整数
  • ZOO_SERVERS 中的 0.0.0.0 表示当前节点自身
  • ZOO_STANDALONE_ENABLED=false 强制启用集群模式

4. 启动与验证集群

4.1 一键启动集群

# 后台启动所有服务
docker compose up -d

# 查看容器状态(应显示3个Up状态容器)
docker compose ps

启动过程可能需要1-2分钟完成选举。可以通过日志观察选举过程:

# 查看zoo1的选举日志
docker logs -f zoo1 | grep -i election

4.2 集群健康检查

这是我常用的验证脚本:

#!/bin/bash
for port in 2181 2182 2183; do
  echo "Checking node on port $port..."
  echo "stat" | nc localhost $port | grep Mode
  echo "----------------------------------"
done

预期输出类似:

Checking node on port 2181...
Mode: follower
----------------------------------
Checking node on port 2182...
Mode: leader
----------------------------------
Checking node on port 2183...
Mode: follower
----------------------------------

4.3 客户端连接测试

使用官方zkCli.sh进行跨节点写入验证:

# 连接到zoo1写入数据
docker exec -it zoo1 zkCli.sh -server localhost:2181 create /testcluster "hello"

# 从zoo3查询数据(应能读取到)
docker exec -it zoo3 zkCli.sh -server localhost:2181 get /testcluster

5. 生产环境优化建议

5.1 性能调优参数

conf/zoo.cfg 中添加这些配置:

# 提高快照和日志清理频率(单位:小时)
autopurge.purgeInterval=1
autopurge.snapRetainCount=5

# 增大客户端连接数限制
maxClientCnxns=1000

# 调整JVM堆大小(根据物理内存调整)
environment:
  JVMFLAGS: "-Xms4G -Xmx4G -XX:+UseG1GC"

5.2 监控方案

推荐组合使用这些方法:

  1. 四字命令监控
    echo mntr | nc localhost 2181
    
  2. Prometheus+Granfa
    environment:
      ZOO_CFG_EXTRA: "metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider metricsProvider.httpPort=7000"
    
  3. 日志告警 :监控 WARN ERROR 级别日志

5.3 灾备演练

定期模拟节点故障,验证集群自愈能力:

# 随机停止一个节点
docker stop zoo$(shuf -i 1-3 -n 1)

# 观察剩余节点日志(应自动重新选举)
docker compose logs -f | grep -i election

# 恢复节点后检查数据一致性
docker start zoo1
docker exec -it zoo1 zkCli.sh -server localhost:2181 sync /testcluster

6. 常见问题排查

选举问题 :如果长时间没有Leader,检查:

  • 防火墙是否开放2888/3888端口
  • 节点间时钟是否同步(建议部署NTP服务)
  • ZOO_SERVERS 配置是否包含所有节点

连接问题 :客户端报ConnectionLoss时:

# 检查每个节点的连接数
echo cons | nc localhost 2181

# 查看网络延迟
docker network inspect zk_zk_net

数据不一致 :手动触发同步:

docker exec -it zoo1 zkCli.sh -server localhost:2181 sync /
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐