Zookeeper集群搭建:三节点伪分布式到生产环境的配置与排错
Zookeeper集群搭建的核心是三件事:每台机器有独立且唯一的myid、zoo.cfg里写全所有节点地址、节点之间端口互通。
只要这三点满足,三台机器就能组成一个可用的集群。
下面按零基础能照做的顺序展开。
先确认环境和前提
Zookeeper是Java写的,所以每台机器都需要JDK。
建议用JDK 8或JDK 11,装完用java -version确认能输出版本号。
集群至少需要3个节点,因为Zookeeper的选举机制要求存活节点超过半数,3节点允许挂1台,2节点反而比单机更脆弱。
准备三台Linux服务器,假设IP为:
192.168.1.101 zk1
192.168.1.102 zk2
192.168.1.103 zk3
每台机器上执行以下检查:
java -version
hostname -I
systemctl status firewalld
如果用的是云服务器,还要确认安全组已经放行2181、2888、3888三个端口。2181是客户端连接端口,2888用于集群内数据同步,3888用于选举通信。
安装包下载与目录规划
在三台机器上分别下载并解压Zookeeper。
以稳定版3.8.x为例,实际下载地址请以Apache官网当前提供的版本为准:
cd /opt
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
mv apache-zookeeper-3.8.4-bin zookeeper
注意要下载带-bin的包,不带-bin的只有源码,启动时会缺少依赖。
进入配置目录:
cd /opt/zookeeper/conf
cp zoo_sample.cfg zoo.cfg
修改zoo.cfg与设置myid
三台机器的zoo.cfg内容基本一致,关键差异在server.x的编号要和本机myid对应。
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper/data
datalogDir=/data/zookeeper/datalog
clientPort=2181
server.1=192.168.1.101:2888:3888
server.2=192.168.1.102:2888:3888
server.3=192.168.1.103:2888:3888
dataDir和datalogDir建议分开,避免事务日志和快照互相影响。
创建目录:
mkdir -p /data/zookeeper/data /data/zookeeper/datalog
然后在每台机器的dataDir下创建myid文件,内容只能是数字,不能有多余空格或换行符。
zk1写1,zk2写2,zk3写3:
echo 1 > /data/zookeeper/data/myid
这是最容易出错的一步:myid的数字必须和zoo.cfg中server.x的x一致,否则节点启动后会反复选举或直接报错。
放行端口并启动
如果开了firewalld,三台机器都要放行:
firewall-cmd --permanent --add-port=2181/tcp
firewall-cmd --permanent --add-port=2888/tcp
firewall-cmd --permanent --add-port=3888/tcp
firewall-cmd --reload
云服务器还要在控制台安全组里放行同样的端口,两层都要开,缺一个就连不通。
启动命令:
/opt/zookeeper/bin/zkServer.sh start
三台都启动后,用jps应该能看到QuorumPeerMain进程。
如果看不到,先去/opt/zookeeper/logs或dataDir下的日志里找原因。
验证集群是否真的可用
先看单机角色:
/opt/zookeeper/bin/zkServer.sh status
正常输出会显示leader或follower,三台里只有一个leader。
如果显示standalone,说明它没加入集群,通常是myid或server.x配置不对。
再用四字命令确认整体状态:
echo stat | nc 192.168.1.101 2181
echo mntr | nc 192.168.1.102 2181
stat能看到连接数和节点角色,mntr能看到zk_followers、zk_synced_followers等指标。
如果zk_synced_followers为0,说明follower没同步上,要回头查2888端口和防火墙。
连上客户端做个简单读写测试:
/opt/zookeeper/bin/zkCli.sh -server 192.168.1.101:2181
create /test hello
ls /
get /test
能创建并读回hello,说明集群基本可用。
几个高频坑
myid写成了带空格的字符串。
用cat -A /data/zookeeper/data/myid检查,正常应该只显示数字,没有^I或$之类多余字符。
只放行了2181。
客户端能连上,但节点之间无法同步,status会一直卡在选举状态。
三个端口都要放行。
dataDir指向了不存在的目录。
Zookeeper不会自动创建多级目录,启动会直接失败,提前mkdir -p建好。
时间不同步。
节点之间时间差太大可能影响选举和会话,建议开启NTP同步,用timedatectl确认时间状态。
集群节点数用了偶数。
4节点容错能力并不比3节点强,反而更容易出现脑裂风险,生产环境优先用3、5、7这类奇数节点。
常见疑问
Zookeeper集群搭建必须用三台物理机吗? 不一定。
学习和测试可以用一台机器开三个端口,配置不同的dataDir和clientPort即可。
但生产环境建议至少三台独立机器,避免单点故障。
启动后一直报“Cannot open channel to x at election address”怎么办? 先确认目标IP和3888端口能通,再检查目标节点是否已经启动。
如果只有一台在运行,它无法单独完成选举,这是正常现象,把三台都启动即可。
能不能用Docker搭? 可以,思路和上面一致:每个容器挂载不同的myid和zoo.cfg,暴露2181、2888、3888,并用宿主机网络或自定义网络保证容器间可解析。
关键仍是myid唯一、server.x写全。
集群搭好后怎么加节点? 在zoo.cfg里追加新的server.x,给新节点写对应myid,然后按顺序滚动重启各节点。
重启期间集群可能短暂不可写,建议在业务低峰操作。
只要myid、端口、server.x三处对齐,Zookeeper集群搭建本身并不复杂。
真正花时间的是排错,所以搭完先用status和mntr确认同步状态,再接入Kafka或HBase等上层服务,能省掉很多后续麻烦。