Zookeeper 是一个开源的分布式协调服务,主要用于解决分布式系统中的数据一致性和协调问题。其核心设计目标是提供高性能、高可用且严格有序的分布式一致性服务。以下是其工作原理的核心要点:
1. 架构角色
Zookeeper 集群由多个节点(服务器)组成,角色分为以下三种:
- Leader:
- 负责处理所有写请求(如创建节点、更新数据等)。
- 通过 ZAB 协议(Zookeeper Atomic Broadcast)保证写操作的全局顺序性。
- 集群中只有一个 Leader,通过选举产生。
- Follower:
- 处理客户端的读请求(直接返回本地数据)。
- 参与 Leader 选举投票。
- 接收 Leader 的写操作提案(Proposal),进行事务日志的持久化和数据同步。
- Observer(可选):
- 仅处理读请求,不参与投票,用于横向扩展读性能。
- 同步 Leader 的数据,但不影响写操作的吞吐量。
2. 数据模型:ZNode
Zookeeper 的数据以树形结构(类似文件系统)存储,每个节点称为 ZNode:
- 持久节点(Persistent):手动创建和删除,长期存在。
- 临时节点(Ephemeral):与客户端会话绑定,会话结束自动删除(用于服务发现、心跳检测)。
- 顺序节点(Sequential):节点名称自动附加全局唯一递增序号(用于分布式锁、队列)。
每个 ZNode 存储少量数据(默认上限 1MB),并维护版本号(version
)和访问控制列表(ACL)。
3. ZAB 协议(一致性核心)
ZAB 协议是 Zookeeper 实现数据一致性的核心算法,分为两个阶段:
(1)崩溃恢复模式(Leader 选举)
- 当 Leader 宕机或集群启动时,进入崩溃恢复模式。
- 所有节点通过 Fast Leader Election 算法选举新 Leader,优先选择事务 ID(ZXID)最大的节点。
- 新 Leader 与 Follower 同步数据,确保所有节点状态一致。
(2)消息广播模式(正常写入)
- Leader 将写请求转换为事务(Proposal),广播给所有 Follower。
- Follower 将 Proposal 写入本地事务日志,并返回确认(ACK)。
- 当收到多数节点(Quorum)的 ACK 后,Leader 提交事务并通知 Follower 更新数据。
4. 请求处理流程
写请求:
- 客户端向任意节点发送写请求。
- 若接收到请求的是 Follower/Observer,则转发给 Leader。
- Leader 生成事务 Proposal,广播给所有 Follower。
- 收到多数节点的 ACK 后,Leader 提交事务并返回成功响应。
读请求:
- 直接由任意节点(Leader/Follower/Observer)处理,返回本地数据(可能读取到旧数据)。
- 可通过
sync
命令强制从 Leader 同步最新数据,确保读取一致性。
5. 客户端会话(Session)
- 客户端与 Zookeeper 服务器建立长连接会话(Session)。
- 会话通过心跳(Heartbeat)维持活性,超时未通信则会话失效,相关临时节点被删除。
- 会话事件(如连接断开、过期)会触发 Watcher 通知。
6. Watch 机制
- 客户端可为某个 ZNode 注册 Watcher 监听器。
- 当 ZNode 数据变更或子节点列表变化时,触发 Watcher 通知(一次性触发,需重新注册)。
7. 一致性保证
Zookeeper 提供以下一致性语义:
- 顺序一致性:所有写操作按全局顺序执行。
- 原子性:事务要么全集群生效,要么不生效。
- 最终一致性:读请求可能返回旧数据,但最终会同步到最新状态。
- 线性一致性写入:所有写操作通过 Leader 串行处理。
8. 典型应用场景
- 分布式锁:通过临时顺序节点和 Watcher 实现。
- 配置管理:集中存储配置信息,通过 Watcher 实时通知变更。
- 服务注册与发现:临时节点表示服务实例,动态维护可用服务列表。
- Leader 选举:通过创建最小序号节点确定 Leader。
9.总结
Zookeeper 通过 ZAB 协议实现分布式一致性,结合 ZNode 数据模型和 Watch 机制,为分布式系统提供可靠的协调服务。其核心优势在于简单高效的架构设计,适用于对一致性和可靠性要求较高的场景。