ZooKeeper 集群角色详解:Leader、Follower、Observer 职责全解析
ZooKeeper 集群角色详解:Leader、Follower、Observer 职责全解析
-
- 一、集群角色概述
-
- 1.1 为什么需要多种角色?
- 1.2 三种角色概览
- 1.3 角色架构图
- 二、Leader 角色:集群的核心
-
- 2.1 Leader 的核心职责
- 2.2 Leader 处理写请求的流程
- 2.3 Leader 的选举过程
- 2.4 Leader 的代码示例
- 三、Follower 角色:集群的基石
-
- 3.1 Follower 的核心职责
- 3.2 Follower 的工作流程
- 3.3 Follower 参与投票的机制
- 3.4 Follower 的配置
- 四、Observer 角色:读扩展的利器
-
- 4.1 Observer 的核心职责
- 4.2 Observer 与 Follower 的区别
- 4.3 Observer 的工作流程
- 4.4 Observer 的配置方法
- 4.5 Observer 的代码实现
- 五、角色之间的交互流程
-
- 5.1 写操作完整流程
- 5.2 读请求负载均衡
- 5.3 故障转移流程
- 六、角色数量配置建议
-
- 6.1 过半机制与角色数量
- 6.2 不同规模集群的角色配置
- 6.3 配置建议表
- 七、实战:查看节点角色
-
- 7.1 使用四字命令查看
- 7.2 使用 zkServer.sh 查看
- 7.3 使用监控指标
- 八、角色选择指南
-
- 8.1 角色决策树
- 8.2 场景化选择建议
- 8.3 最佳实践
- 九、总结
-
- 9.1 角色职责速查表
- 9.2 角色体系的价值
- 9.3 一句话总结
|
🌺The Begin🌺点点关注,收藏不迷路🌺
|
摘要:在 ZooKeeper 集群中,不同节点扮演着不同的角色,共同协作以实现高可用、高性能的分布式协调服务。理解这些角色的职责分工,是掌握 ZooKeeper 架构设计的关键。本文将深入剖析 Leader、Follower、Observer 三种角色的核心职责、交互流程以及配置方法,帮助读者全面了解 ZooKeeper 集群的角色体系。
一、集群角色概述
1.1 为什么需要多种角色?
ZooKeeper 作为分布式协调服务,需要在高可用、高性能和一致性之间取得平衡。单一角色的设计无法满足这些需求,因此引入了三种角色:
ZooKeeper角色
Leader
核心处理者
写请求入口
事务协调
Follower
读请求处理
投票参与者
故障时参与选举
Observer
读扩展者
不参与投票
跨机房部署
1.2 三种角色概览
| 角色 | 数量 | 参与投票 | 处理读请求 | 处理写请求 | 主要职责 |
|---|---|---|---|---|---|
| Leader | 唯一 | ✅ | ✅ | ✅ | 处理所有写请求、协调事务、发起投票 |
| Follower | 多个 | ✅ | ✅ | ❌(转发给 Leader) | 处理读请求、参与选举和投票 |
| Observer | 多个 | ❌ | ✅ | ❌(转发给 Leader) | 扩展读能力,不参与投票 |
1.3 角色架构图
ZooKeeper 集群
投票/同步
投票/同步
投票/同步
仅同步
仅同步
读写
只读
只读
只读
Leader 节点
唯一
Follower 节点1
Follower 节点2
Follower 节点3
Observer 节点1
Observer 节点2
客户端
客户端
客户端
客户端
二、Leader 角色:集群的核心
2.1 Leader 的核心职责
Leader 是 ZooKeeper 集群中唯一的写请求处理器,负责维护整个集群的数据一致性。
| 职责 | 说明 | 重要性 |
|---|---|---|
| 处理写请求 | 所有写请求必须经过 Leader,由 Leader 分配全局唯一的 ZXID | ⭐⭐⭐⭐⭐ |
| 事务协调 | 将写请求转化为 Proposal,广播给所有 Follower 并收集 ACK | ⭐⭐⭐⭐⭐ |
| 数据同步 | 确保所有 Follower 的数据与 Leader 保持一致 | ⭐⭐⭐⭐ |
| 心跳检测 | 定期向 Follower 发送心跳,检测节点存活状态 | ⭐⭐⭐ |
| 发起选举 | 当检测到自身故障或网络分区时,主动让出 Leader 地位 | ⭐⭐⭐ |
2.2 Leader 处理写请求的流程
Follower3
Follower2
Follower1
Leader
客户端
Follower3
Follower2
Follower1
Leader
客户端
5. 收到过半 ACK
1. 写请求
2. 生成 Proposal,分配 ZXID
3. PROPOSAL(ZXID)
3. PROPOSAL(ZXID)
3. PROPOSAL(ZXID)
4. ACK
4. ACK
6. COMMIT
6. COMMIT
6. COMMIT
7. 返回成功
2.3 Leader 的选举过程
当 Leader 故障时,集群会重新选举新的 Leader:
对方 ZXID 更大
自己 ZXID 更大
ZXID 相等
对方 myid 更大
自己 myid 更大
否
是
Leader 故障
剩余节点进入 LOOKING 状态
发起投票 (myid, lastZxid)
交换投票
比较投票规则
更新投票给对方
保持自己投票
比较 myid
统计得票
得过半票数?
选出新 Leader
Leader 选举规则:
- 优先比较 ZXID:ZXID 越大表示数据越新,优先当选
- ZXID 相同时:比较 myid,myid 大的优先
- 需要过半票数:得票必须超过集群总节点数的一半
2.4 Leader 的代码示例
// Leader 的核心处理逻辑(简化版)
public class Leader {
private ZooKeeperServer zkServer;
private List<LearnerHandler> followers = new ArrayList<>();
/**
* 处理写请求
*/
public void processWriteRequest(Request request) throws Exception {
// 1. 生成 Proposal
long zxid = zkServer.getNextZxid();
Proposal proposal = new Proposal(zxid, request);
// 2. 广播给所有 Follower
broadcastProposal(proposal);
// 3. 等待 ACK(过半机制)
waitForAcks(proposal, followers.size() / 2 + 1);
// 4. 提交事务
commitProposal(proposal);
}
/**
* 心跳检测
*/
public void checkHeartbeat() {
for (LearnerHandler follower : followers) {
if (!follower.isAlive()) {
removeFollower(follower);
}
}
}
}
三、Follower 角色:集群的基石
3.1 Follower 的核心职责
Follower 是 ZooKeeper 集群中数量最多的节点,负责处理读请求并参与投票。
| 职责 | 说明 | 重要性 |
|---|---|---|
| 处理读请求 | 直接从本地内存读取数据,返回给客户端 | ⭐⭐⭐⭐⭐ |
| 参与投票 | 在 Leader 选举和事务提交时投票 | ⭐⭐⭐⭐⭐ |
| 转发写请求 | 收到写请求后转发给 Leader | ⭐⭐⭐ |
| 数据同步 | 与 Leader 保持数据一致 | ⭐⭐⭐⭐ |
| 发送心跳 | 定期向 Leader 发送心跳,报告存活状态 | ⭐⭐⭐ |
3.2 Follower 的工作流程
Leader
Follower
写客户端
读客户端
Leader
Follower
写客户端
读客户端
6. Leader 处理
1. 读请求
2. 本地内存读取
3. 返回数据
4. 写请求
5. 转发给 Leader
7. 返回结果
8. 返回结果
3.3 Follower 参与投票的机制
public class Follower {
private ZooKeeperServer zkServer;
private Leader leader;
/**
* 处理 Leader 的提案
*/
public void processProposal(Proposal proposal) throws Exception {
// 1. 写入事务日志
zkServer.getZKDatabase().append(proposal);
// 2. 发送 ACK 给 Leader
leader.sendAck(proposal);
// 3. 等待 Leader 的 COMMIT
waitForCommit(proposal.getZxid());
// 4. 应用到内存
zkServer.getZKDatabase().processTxn(proposal);
}
/**
* 参与 Leader 选举
*/
public void startElection() {
// 1. 状态变为 LOOKING
setState(ServerState.LOOKING);
// 2. 发起投票
Vote vote = new Vote(getMyId(), getLastZxid());
electionManager.sendVote(vote);
// 3. 等待选举结果
}
}
3.4 Follower 的配置
# zoo.cfg 中 Follower 的配置(默认角色)
server.1=192.168.1.10:2888:3888
server.2=192.168.1.11:2888:3888
server.3=192.168.1.12:2888:3888
# Follower 不需要特殊配置,默认即为 Follower
四、Observer 角色:读扩展的利器
4.1 Observer 的核心职责
Observer 是 ZooKeeper 3.3.0+ 引入的特殊角色,用于水平扩展读能力而不影响写性能。
| 职责 | 说明 | 重要性 |
|---|---|---|
| 处理读请求 | 直接从本地内存读取数据 | ⭐⭐⭐⭐⭐ |
| 数据同步 | 异步从 Leader 同步数据 | ⭐⭐⭐⭐ |
| 不参与投票 | 不参与 Leader 选举和事务投票 | ⭐⭐⭐ |
| 跨机房部署 | 可在异地机房部署,本地读请求 | ⭐⭐⭐ |
4.2 Observer 与 Follower 的区别
| 方面 | Follower | Observer |
|---|---|---|
| 是否投票 | ✅ 参与投票 | ❌ 不参与投票 |
| 对写性能影响 | 需要等待 ACK,影响写延迟 | 无影响,异步同步 |
| 可扩展性 | 有限(投票节点过多影响性能) | 可任意扩展 |
| 适用场景 | 核心集群节点 | 读扩展、跨机房 |
4.3 Observer 的工作流程
Follower
Leader
Observer
读客户端
Follower
Leader
Observer
读客户端
Observer 不参与投票
5. 更新本地内存
Follower 参与投票
Observer 只同步,不 ACK
1. 读请求
2. 本地读取
3. 返回数据
4. 异步同步数据
6. 同步数据(同步方式)
7. ACK(必须)
4.4 Observer 的配置方法
# zoo.cfg 中配置 Observer
# 在节点定义后加上 :observer 标记
server.1=192.168.1.10:2888:3888
server.2=192.168.1.11:2888:3888
server.3=192.168.1.12:2888:3888
server.4=192.168.1.13:2888:3888:observer # Observer 节点
server.5=192.168.1.14:2888:3888:observer # Observer 节点
# 在 Observer 节点的 zoo.cfg 中还需指定
peerType=observer
4.5 Observer 的代码实现
public class Observer {
private ZooKeeperServer zkServer;
private Leader leader;
/**
* Observer 接收 Leader 的数据同步
*/
public void syncWithLeader(Leader leader) throws Exception {
// 1. 发送 FOLLOWERINFO(但标记为 Observer)
sendObserverInfo(leader);
// 2. 接收同步指令
QuorumPacket qp = leader.readPacket();
// 3. 根据指令同步数据(DIFF/SNAP/TRUNC)
syncData(qp);
// 4. 发送 ACK(但 Leader 不会等待 Observer 的 ACK)
sendAck();
}
/**
* 处理读请求
*/
public byte[] handleReadRequest(String path) throws Exception {
// 直接从本地内存读取
return zkServer.getZKDatabase().getData(path);
}
}
五、角色之间的交互流程
5.1 写操作完整流程
其他Follower
Leader
Observer
Follower
客户端
其他Follower
Leader
Observer
Follower
客户端
6. 收到过半 ACK
1. 写请求(连接到 Follower)
2. 转发给 Leader
3. 生成 Proposal,分配 ZXID
4. 广播 Proposal
4. 广播 Proposal
4. 广播 Proposal(异步)
5. ACK
5. ACK
7. COMMIT
7. COMMIT
7. COMMIT(异步)
8. 返回结果
9. 返回结果
5.2 读请求负载均衡
客户端连接策略
读请求
读请求
读请求
读请求
写请求
客户端
Follower1
Follower2
Observer1
Observer2
Leader
5.3 故障转移流程
Leader
Follower2
Follower1
客户端
Leader
Follower2
Follower1
客户端
Leader 故障
选出新 Leader
F1 成为新 Leader
检测到 Leader 失联
检测到 Leader 失联
进入选举流程
交换投票
客户端重连
继续提供服务
六、角色数量配置建议
6.1 过半机制与角色数量
| 总节点数 | Follower 数 | 可容忍故障 | Observer 数 |
|---|---|---|---|
| 3 | 2 | 1 | 可任意添加 |
| 5 | 4 | 2 | 可任意添加 |
| 7 | 6 | 3 | 可任意添加 |
6.2 不同规模集群的角色配置
需要多大的集群?
中小规模
大规模
跨地域部署
3节点: 1 Leader + 2 Follower
5节点: 1 Leader + 4 Follower
核心集群: 5 Follower
边缘机房: 多个 Observer
6.3 配置建议表
| 场景 | Leader | Follower | Observer | 说明 |
|---|---|---|---|---|
| 开发测试 | 1 | 2 | 0 | 最小集群,测试功能 |
| 生产环境 | 1 | 4 | 0 | 标准 5 节点集群 |
| 读压力大 | 1 | 4 | 2-10 | 添加 Observer 扩展读能力 |
| 跨地域部署 | 1 | 4 | 每个机房 2-3 | 异地读本地化 |
七、实战:查看节点角色
7.1 使用四字命令查看
# 查看节点角色
echo stat | nc localhost 2181 | grep Mode
# 输出示例
Mode: leader # Leader 节点
Mode: follower # Follower 节点
Mode: observer # Observer 节点
7.2 使用 zkServer.sh 查看
# 使用状态命令
./zkServer.sh status
# 输出示例
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: follower
7.3 使用监控指标
# 通过 mntr 命令获取详细角色信息
echo mntr | nc localhost 2181 | grep zk_server_state
zk_server_state follower
八、角色选择指南
8.1 角色决策树
是
否
是
否
节点需要承担什么职责?
需要处理写请求?
配置为 Leader
唯一
需要参与投票?
配置为 Follower
支持集群扩展
配置为 Observer
读扩展
8.2 场景化选择建议
| 需求场景 | 推荐角色 | 理由 |
|---|---|---|
| 核心处理节点 | Leader | 唯一写入口,必须存在 |
| 扩展读能力 | Observer | 不影响写性能,可无限添加 |
| 增强投票可靠性 | Follower | 增加投票节点,提高容错 |
| 跨机房部署 | Observer | 避免跨机房投票延迟 |
| 开发测试 | Follower | 便于调试,灵活切换 |
8.3 最佳实践
- Leader 必须唯一:集群中有且仅有一个 Leader
- Follower 奇数个:3 或 5 个,配合过半机制
- Observer 可任意:按需扩展,无数量限制
- 投票节点不少于 3 个:保证选举可用性
- 跨机房部署用 Observer:避免异地机房参与投票
九、总结
9.1 角色职责速查表
| 角色 | 读请求 | 写请求 | 投票 | 选举 | 数据同步 |
|---|---|---|---|---|---|
| Leader | ✅ | ✅ | ✅ | 被选举 | 同步给其他人 |
| Follower | ✅ | ❌(转发) | ✅ | 参与选举 | 从 Leader 同步 |
| Observer | ✅ | ❌(转发) | ❌ | 不参与 | 从 Leader 同步 |
9.2 角色体系的价值
ZooKeeper 角色体系的价值
唯一写入口
投票参与
读扩展
Leader
保证一致性
Follower
保证可用性
Observer
保证性能
高可靠分布式协调
9.3 一句话总结
ZooKeeper 集群通过 Leader 保障写一致性,通过 Follower 提供投票机制保证高可用,通过 Observer 实现读扩展,三种角色各司其职、协同工作,共同构建了一个高性能、高可靠、可扩展的分布式协调服务。

|
🌺The End🌺点点关注,收藏不迷路🌺
|