zookeeper(分布式应用程序协调服务软件)的本地部署
一.ZooKeeper的基础知识
1. 定义
ZooKeeper 是一个开源的分布式协调框架,其核心定位是为分布式应用提供一致性服务。它简化了分布式系统中的复杂协调任务(如集群管理、配置同步等),充当整个分布式系统的“管理员”角色。通过封装易出错的关键服务,ZooKeeper 向用户提供高效、稳定且易用的接口,广泛应用于大数据领域的分布式系统中。
2. 特点
ZooKeeper 的主要特点包括:
- 一致性保障:提供强一致性(顺序一致性和原子性),确保分布式系统中所有节点对数据状态达成一致。
- 高可用性:支持集群部署(通常由奇数个节点组成),具备自动故障转移能力,即使部分节点失效,服务也能持续运行。
- 简单易用:提供简洁的 API(如创建节点、监听事件),并支持图形用户界面(GUI)工具,简化集群管理和监控,无需深入命令行操作。
- 高性能与可扩展性:设计优化了低延迟读写操作(例如,读操作可直接由 Follower 节点处理),适用于大规模分布式环境。
- 应用场景广泛:常用于数据发布/订阅、负载均衡、命名服务、分布式锁、Master 选举等场景,是 Hadoop、Kafka 等系统的核心组件。
3. 工作方式
ZooKeeper 的工作基于 ZAB 协议(ZooKeeper Atomic Broadcast) ,这是一种主从架构的共识协议。集群由多个节点(通常为 3、5 或 7 个)组成,节点角色包括:
- Leader:负责处理所有写请求,协调数据变更。
- Follower:处理读请求,并参与写请求的投票与同步。
- Observer(可选):只处理读请求,不参与投票,用于扩展读性能。
工作流程的核心步骤:
- 客户端请求:客户端连接到任意节点(如 Follower),发送请求(如创建节点或读取数据)。
- 请求路由:
- 读请求:直接由接收节点处理并返回结果。
- 写请求:被转发到 Leader 节点。
- Leader 协调:Leader 将写请求广播为“提议”(proposal)给所有 Follower 节点。
- 投票与提交:Follower 节点投票确认提议;当多数节点(如过半节点)达成共识后,Leader 提交变更(commit)并通知所有节点。
- 数据同步:所有节点同步更新数据状态,确保一致性。
- 响应客户端:Leader 或接收节点返回操作结果给客户端。
这个过程保证了分布式环境下的数据一致性和容错性。ZooKeeper 还支持“Watch 机制”,允许客户端注册事件监听(如节点变更),实现实时通知。
4. 工作流程图
为了直观展示 ZooKeeper 的工作方式,我创建了一个简化流程图(基于 ZAB 协议)。该图描述了写请求的处理流程(读请求更简单,由 Follower 直接处理):
流程图解释:
- 客户端发起写请求(例如,创建节点)。
- 请求被 Follower 节点接收并转发给 Leader。
- Leader 广播提议给所有 Follower 节点。
- Follower 节点投票;如果多数节点(例如 3 个中的 2 个)同意,Leader 提交变更。
- Leader 通知所有节点同步数据。
- 最终,响应通过原节点返回给客户端。
此流程确保了数据一致性和系统可靠性,是 ZooKeeper 的核心工作方式。
二、下载zookeeper
-
访问官网
打开ZooKeeper官方下载页面:https://zookeeper.apache.org/releases.html2 -
选择版本
- 当前稳定版本:3.5.6(2023年最新)或更高版本3
- 推荐选择带
-bin后缀的预编译版本(如:apache-zookeeper-3.5.6-bin.tar.gz)
-
下载方式
# Linux/Mac 使用 wget 直接下载(示例) sudo wget https://archive.apache.org/dist/zookeeper/zookeeper-3.5.6/apache-zookeeper-3.5.6-bin.tar.gz或手动下载压缩包后上传到服务器
三、Linux 环境安装流程
-
安装(所有节点)
sudo wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz sudo tar -zxvf zookeeper-3.4.14.tar.gz -C /opt sudo mv /opt/zookeeper-3.4.14 /opt/zookeeper -
配置文件
vim /opt/zookeeper/conf/zoo.cfgzoo.cfg内容:
# 示例配置 tickTime=2000 initLimit=10 syncLimit=5 dataDir=/opt/zookeeper/data # 确保此目录存在且有写权限 clientPort=2181 # 集群节点配置(关键部分) server.1=192.168.10.102:2888:3888 server.2=192.168.10.103:2888:3888 server.3=192.168.10.104:2888:3888 -
myid配置
sudo mkdir /opt/zookeeper/data # 在hadoop102上执行: echo "1" > /opt/zookeeper/data/myid # 在hadoop103上执行: echo "2" > /opt/zookeeper/data/myid # 在hadoop104上执行: echo "3" > /opt/zookeeper/data/myid
四、集群初始化与启动
-
同步配置
scp -r /opt/zookeeper hadoop103:/opt/ scp -r /opt/zookeeper hadoop104:/opt/ -
启动ZooKeeper集群
# 所有节点执行 /opt/zookeeper/bin/zkServer.sh start /opt/zookeeper/bin/zkServer.sh status # 验证状态
出事了!突然发现我的三台虚拟机之间网络不通…
1、核心问题总览
初始状态:hadoop102/hadoop103/hadoop104 执行 zkServer.sh status 均显示 Mode: standalone(单机模式),无法组成集群;部分节点启动时提示 FAILED TO START,跨节点通信(如 telnet 3888 端口)失败。
2、分阶段问题解决过程
阶段 1:配置层排查(最基础、最易出错)
现象
- 集群启动后仍为
standalone; - 启动日志提示
Invalid config或Cannot find myid。
核心排查点
zoo.cfg配置一致性- 检查
dataDir路径是否纯净(无注释,如dataDir=/opt/zookeeper/data,而非dataDir=/opt/zookeeper/data # 注释); - 检查
server.x列表是否完整(server.1=hadoop102:2888:3888、server.2=hadoop103:2888:3888、server.3=hadoop104:2888:3888); - 确保 3 台节点的
zoo.cfg内容完全一致。
- 检查
myid文件正确性- 检查
dataDir目录下是否存在myid文件; - 确保
myid内容与server.x对应(hadoop102=1、hadoop103=2、hadoop104=3),且文件无多余字符(如空格、换行)。
- 检查
解决方案
# 1. 统一3台节点的 zoo.cfg 配置(以 hadoop102 为例)
vim /opt/zookeeper/conf/zoo.cfg # 修正 dataDir 和 server 列表
scp /opt/zookeeper/conf/zoo.cfg hadoop103:/opt/zookeeper/conf/ # 同步到103
scp /opt/zookeeper/conf/zoo.cfg hadoop104:/opt/zookeeper/conf/ # 同步到104
# 2. 修复 myid 文件(以 hadoop103 为例)
echo 2 > /opt/zookeeper/data/myid # 写入正确的 myid
cat /opt/zookeeper/data/myid # 验证内容
验证方式
- 执行
cat /opt/zookeeper/conf/zoo.cfg对比 3 台节点配置; - 执行
cat /opt/zookeeper/data/myid确认每台节点的myid正确。
阶段 2:服务启动层排查(日志是关键)
现象
- 执行
zkServer.sh start提示FAILED TO START; jps命令无QuorumPeerMain进程(ZooKeeper 主进程)。
核心排查点
- 启动日志分析:ZooKeeper 启动日志默认存于
bin/zookeeper.out,错误信息多源于权限、端口占用、配置错误。 - 数据目录权限:
dataDir目录需有读写权限,否则无法创建临时文件。 - 端口占用:
2181(客户端端口)、2888(数据同步端口)、3888(选举端口)可能被其他进程占用。
解决方案
# 1. 查看启动日志,定位错误(以 hadoop103 为例)
tail -n 50 /opt/zookeeper/bin/zookeeper.out
# 2. 修复常见错误
# 错误1:Permission denied → 修复 dataDir 权限
chmod -R 755 /opt/zookeeper/data
# 错误2:Address already in use → 杀死占用端口的进程(如3888)
ss -tuln | grep 3888 # 查看占用进程
kill -9 <占用进程号>
# 3. 清理旧数据,避免残留状态干扰
rm -rf /opt/zookeeper/data/version-2 /opt/zookeeper/data/log.*
# 4. 重新启动服务
/opt/zookeeper/bin/zkServer.sh start
验证方式
- 执行
jps确认存在QuorumPeerMain进程; - 执行
ss -tuln | grep 3888确认 3888 端口已监听(输出类似tcp LISTEN 0 50 ::ffff:192.168.10.103:3888 :::*)。
阶段 3:网络连通层排查(最常见 “隐形障碍”)
现象
- 服务启动正常(进程、端口均存在),但集群仍为
standalone; - 执行
telnet hadoop103 3888提示Connection refused或Timeout。
核心排查点
- 防火墙拦截:
firewalld或iptables未关闭,阻止 3888/2888 端口通信; - SELinux 拦截:Linux 强制访问控制机制,默认可能拦截非标准端口;
- 主机名解析:
/etc/hosts未配置集群节点映射,导致节点无法通过主机名找到彼此。
解决方案
# 1. 关闭防火墙(3台节点均执行)
# 关闭 firewalld
systemctl stop firewalld
systemctl disable firewalld
firewall-cmd --state # 验证状态为 inactive
# 关闭 iptables
iptables -F # 清空规则
systemctl stop iptables
systemctl disable iptables
iptables -L # 验证规则为空
# 2. 关闭 SELinux(3台节点均执行)
# 临时关闭(立即生效)
setenforce 0
# 永久关闭(重启生效)
vim /etc/selinux/config # 将 SELINUX=enforcing 改为 SELINUX=disabled
# 3. 配置主机名解析(3台节点均执行)
echo "192.168.10.102 hadoop102" >> /etc/hosts
echo "192.168.10.103 hadoop103" >> /etc/hosts
echo "192.168.10.104 hadoop104" >> /etc/hosts
验证方式
- 执行
telnet hadoop103 3888(从 hadoop102 操作),显示Connected to hadoop103即成功; - 执行
ping hadoop104(从 hadoop102 操作),确保网络能通。
阶段 4:集群成功与 Leader 选举(原理理解)
现象
- 3 台节点启动后,等待 10-30 秒,执行
zkServer.sh status显示:- 1 台节点(如
hadoop103):Mode: leader; - 另外 2 台节点(如
hadoop102/hadoop104):Mode: follower。
- 1 台节点(如
Leader 选举核心原理
| 选举指标 | 优先级 | 说明 |
|---|---|---|
zxid(事务 ID) | 高 | 代表数据新鲜度,值越大越优先(新集群初始值均为 0,所有节点相同); |
myid(节点标识) | 低 | 仅当 zxid 相同时生效,值越大越优先; |
| 多数派原则 | 基础 | 需获得超过半数节点投票(3 节点集群需≥2 票)。 |
本次 hadoop103 成为 Leader 的原因
- 启动顺序:
hadoop102→hadoop103→hadoop104; hadoop103启动后,与hadoop102形成 “多数派”(2 票);- 新集群
zxid=0相同,hadoop103的myid=2大于hadoop102的myid=1,因此当选。
阶段 5:扩展操作(手动调整 Leader 为 hadoop102)
核心思路
ZooKeeper 不支持直接指定 Leader,需通过 “提升优先级 + 触发故障转移” 实现。
操作步骤
# 1. 提升 hadoop102 的 zxid(让其数据更“新”)
/opt/zookeeper/bin/zkCli.sh -server hadoop102:2181 # 连接客户端
create /force_leader "test" # 创建节点,增加 zxid
quit # 退出客户端
# 2. 停止当前 Leader(hadoop103)
/opt/zookeeper/bin/zkServer.sh stop
# 3. 验证新 Leader
/opt/zookeeper/bin/zkServer.sh status # hadoop102 显示 Mode: leader
3、ZooKeeper 集群问题解决流程表
| 步骤序号 | 操作内容 | 核心目标 | 验证方式 | |
|---|---|---|---|---|
| 1 | 安装 ZooKeeper,统一 3 台节点版本 | 确保环境一致性 | zkServer.sh version 对比版本 | |
| 2 | 配置 zoo.cfg(dataDir、server 列表),同步到 3 台节点 | 集群基础配置正确 | cat /opt/zookeeper/conf/zoo.cfg 对比 | |
| 3 | 在 3 台节点创建 myid,内容对应 server.x | 节点标识唯一且正确 | cat /opt/zookeeper/data/myid 检查 | |
| 4 | 依次启动 hadoop102→hadoop103→hadoop104 | 启动集群服务 | jps 查看 QuorumPeerMain 进程 | |
| 5 | 执行 zkServer.sh status 检查模式 | 判断集群是否形成 | 若显示 standalone,进入排障 | |
| 6 | 查看 zookeeper.out 日志,定位启动错误 | 解决服务启动失败 | 日志无 ERROR 级信息 | |
| 7 | 执行 `ss -tuln | grep 3888` | 确认端口监听正常 | 输出包含 3888 端口监听信息 |
| 8 | 执行 telnet 目标节点 3888(跨节点) | 验证网络连通性 | 显示 Connected to 目标节点 | |
| 9 | 关闭防火墙(firewalld/iptables)和 SELinux | 消除网络拦截 | firewall-cmd --state 为 inactive,getenforce 为 Permissive | |
| 10 | 重启集群,等待 10-30 秒后检查 status | 确认集群成功 | 1 台 leader,2 台 follower | |
| 11(可选) | 提升目标节点 zxid,停止当前 Leader | 手动调整 Leader | zkServer.sh status 验证新 Leader |
4、核心排障经验总结
- 日志优先:所有问题先查
bin/zookeeper.out,错误信息直接指向根因; - 由内而外:先排查单节点配置 / 服务(进程、端口),再检查跨节点网络;
- 网络是关键:3888/2888 端口必须通畅,防火墙 / SELinux 是最常见拦截因素;
- 干净启动:修改配置后,需清理旧数据(
version-2/log.*),杀死残留进程。
2万+

被折叠的 条评论
为什么被折叠?



