Apache ZooKeeper 教程
欢迎学习 Apache ZooKeeper!本教程将带你从零基础开始,全面掌握 ZooKeeper 的核心知识和技能。
什么是 Apache ZooKeeper?
Apache ZooKeeper 是一个开源的分布式协调服务,专为分布式应用程序设计。它提供了一组简单的原语,分布式应用可以基于这些原语实现更高层次的同步服务、配置维护、组和命名服务。
ZooKeeper 最初由 Yahoo 研发,是 Google Chubby 的开源实现,现已成为 Apache 软件基金会的顶级项目。它的设计目标是简化分布式应用程序的开发,让开发者不必从头实现复杂的协调服务。
核心定义
从技术角度来看,ZooKeeper 实现了以下核心能力:
- 命名服务:提供类似文件系统的层次化命名空间,用于存储和检索数据
- 配置管理:集中管理分布式系统的配置信息,支持动态更新
- 分布式同步:提供分布式锁、屏障等同步原语
- 组服务:管理集群成员关系,实现服务发现和故障检测
ZooKeeper 的设计目标
ZooKeeper 的设计遵循以下核心原则:
简单性:ZooKeeper 提供一个共享的层次化命名空间,类似于标准文件系统的目录树结构。命名空间由数据寄存器(称为 znode)组成,类似于文件和目录。与典型的文件系统不同,ZooKeeper 数据保存在内存中,可以实现高吞吐量和低延迟。
高性能:ZooKeeper 专为高性能而设计,特别是在读多写少的工作负载中表现出色。在读取与写入比例约为 10:1 的情况下,ZooKeeper 的性能最佳。
高可用:ZooKeeper 服务通过复制机制实现高可用性。一组 ZooKeeper 服务器组成一个集群(称为 ensemble),只要大多数服务器可用,服务就能继续运行。
顺序性:ZooKeeper 对每次更新都标记一个数字,反映所有 ZooKeeper 事务的顺序。后续操作可以利用这个顺序实现更高级别的抽象,如同步原语。
ZooKeeper 与其他协调服务的对比
| 特性 | ZooKeeper | etcd | Consul |
|---|---|---|---|
| 一致性协议 | ZAB | Raft | Raft |
| 数据模型 | 层次化命名空间 | 键值对 | 键值对 |
| 语言支持 | Java, C | Go, Java, Python 等 | Go, Java, Python 等 |
| 服务发现 | 需要额外实现 | 原生支持 | 原生支持 |
| 配置管理 | 原生支持 | 原生支持 | 原生支持 |
| 分布式锁 | 原生支持 | 原生支持 | 原生支持 |
| 学习曲线 | 较陡峭 | 平缓 | 平缓 |
ZooKeeper 的应用场景
1. 配置管理
在分布式系统中,配置信息需要集中管理和动态更新。ZooKeeper 可以作为配置中心:
- 将配置信息存储在 ZooKeeper 的 znode 中
- 应用程序启动时从 ZooKeeper 读取配置
- 配置变更时,通过 Watcher 机制通知所有客户端
配置管理示意:
ZooKeeper 集群
┌─────────────────┐
│ /config/app │
│ ├─ db.url │
│ ├─ db.user │
│ └─ timeout │
└────────┬────────┘
│ Watcher 通知
┌────────┼────────┐
▼ ▼ ▼
服务A 服务B 服务C
2. 命名服务
命名服务是通过指定的名字来获取资源或服务的地址。ZooKeeper 可以创建全局唯一的路径作为名字:
- Dubbo 使用 ZooKeeper 维护全局的服务地址列表
- 服务提供者在 ZooKeeper 中注册自己的地址
- 服务消费者从 ZooKeeper 获取服务提供者列表
3. 分布式锁
在分布式环境中,多个进程可能需要互斥地访问共享资源。ZooKeeper 可以实现分布式锁:
- 利用临时节点和顺序节点的特性
- 实现公平锁、共享锁、读写锁等
- 具有锁释放的可靠性(会话断开自动释放)
4. 集群管理
ZooKeeper 可以用于管理集群成员关系:
- 成员加入时创建临时节点
- 成员离开或故障时临时节点自动删除
- 其他成员通过 Watcher 感知成员变化
5. Leader 选举
在分布式系统中,经常需要选举一个主节点来协调工作:
- 利用顺序临时节点实现选举
- 序号最小的节点成为 Leader
- Leader 故障时自动重新选举
6. 分布式队列
ZooKeeper 可以实现简单的分布式队列:
- 利用顺序节点实现 FIFO 队列
- 利用临时节点实现屏障(Barrier)
ZooKeeper 核心概念
数据模型
ZooKeeper 的数据模型是一个层次化的命名空间,类似于 Unix 文件系统:
/
/\
/ \
/zookeeper /app
| /|\
| / | \
config users orders products
每个节点称为 znode,可以存储数据,也可以有子节点。与文件系统不同,znode 既可以像文件一样存储数据,也可以像目录一样包含子节点。
ZNode 类型
ZooKeeper 支持以下类型的 znode:
| 类型 | 说明 | 用途 |
|---|---|---|
| 持久节点 | 节点创建后一直存在,直到被删除 | 配置信息、静态数据 |
| 临时节点 | 会话结束时节点自动删除 | 服务注册、分布式锁 |
| 持久顺序节点 | 持久节点 + 自动递增序号 | 分布式队列、Leader 选举 |
| 临时顺序节点 | 临时节点 + 自动递增序号 | 分布式锁、Leader 选举 |
| 容器节点 | 子节点都被删除后,容器节点可能被删除 | 锁、Leader 选举的父节点 |
| TTL 节点 | 节点在 TTL 时间内未被修改且无子节点则删除 | 临时数据存储 |
会话(Session)
客户端与 ZooKeeper 服务器之间建立 TCP 连接,形成一个会话:
- 会话有超时时间,客户端需要定期发送心跳
- 会话断开后,临时节点会被删除
- 会话可以迁移到不同的服务器(故障转移)
监听器(Watcher)
Watcher 是 ZooKeeper 实现事件通知的机制:
- 客户端可以在 znode 上注册 Watcher
- znode 发生变化时,客户端收到通知
- Watcher 是一次性的,触发后需要重新注册
版本号
每个 znode 维护三个版本号,用于乐观锁:
- version:数据变更次数
- cversion:子节点变更次数
- aversion:ACL 变更次数
ZooKeeper 一致性保证
ZooKeeper 提供以下一致性保证:
- 顺序一致性:客户端的更新操作按照发送顺序应用
- 原子性:更新操作要么成功要么失败,没有中间状态
- 单一系统映像:无论连接到哪个服务器,客户端看到的服务视图相同
- 可靠性:更新一旦被应用,就会持久保存直到被覆盖
- 时效性:客户端的系统视图在一定时间范围内保证是最新的
ZooKeeper 架构
┌─────────────────────────────────────────────────────────────┐
│ ZooKeeper 集群架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 客户端层 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Client1 │ │ Client2 │ │ Client3 │ │ Client4 │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ └───────┼───────────┼───────────┼───────────┼────────┘ │
│ │ │ │ │ │
│ └───────────┴─────┬─────┴───────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ZooKeeper 服务端 │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Leader │ │ Follower │ │ Follower │ │ │
│ │ │ (读写请求) │ │ (读请求) │ │ (读请求) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ 内存数据库 │ │ 内存数据库 │ │ 内存数据库 │ │ │
│ │ │ 事务日志 │ │ 事务日志 │ │ 事务日志 │ │ │
│ │ │ 快照文件 │ │ 快照文件 │ │ 快照文件 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │ │ │ │
│ │ └────────────────┴────────────────┘ │ │
│ │ ZAB 协议 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
组件说明
Leader(领导者):
- 处理所有写请求
- 负责事务的发起和投票
- 维护集群状态
Follower(跟随者):
- 处理读请求
- 参与 Leader 选举
- 参与 write 事务投票
Observer(观察者):
- 不参与投票
- 只处理读请求
- 用于扩展集群读能力
教程目录
基础入门
- 环境安装 - ZooKeeper 安装和配置
- 数据模型与 ZNode - 理解 ZooKeeper 的数据模型
核心机制
客户端开发
- Java 客户端开发 - 使用 Java API 操作 ZooKeeper
进阶应用
知识速查
- 速查表 - ZooKeeper 常用命令速查
学习建议
- 理解原理:深入理解 ZAB 协议、会话机制、Watcher 机制
- 动手实践:搭建 ZooKeeper 集群,使用命令行操作
- 结合场景:结合实际业务场景学习,如分布式锁、配置中心
- 阅读源码:阅读 Curator 等客户端库的源码
- 关注性能:学习 ZooKeeper 的性能调优
参考资料
- Apache ZooKeeper 官方文档
- ZooKeeper Programmer's Guide
- ZooKeeper Administrator's Guide
- Apache Curator 官方文档
准备好开始学习了吗?点击下一章开始你的 ZooKeeper 学习之旅。