跳到主要内容

Apache ZooKeeper 教程

欢迎学习 Apache ZooKeeper!本教程将带你从零基础开始,全面掌握 ZooKeeper 的核心知识和技能。

什么是 Apache ZooKeeper?

Apache ZooKeeper 是一个开源的分布式协调服务,专为分布式应用程序设计。它提供了一组简单的原语,分布式应用可以基于这些原语实现更高层次的同步服务、配置维护、组和命名服务。

ZooKeeper 最初由 Yahoo 研发,是 Google Chubby 的开源实现,现已成为 Apache 软件基金会的顶级项目。它的设计目标是简化分布式应用程序的开发,让开发者不必从头实现复杂的协调服务。

核心定义

从技术角度来看,ZooKeeper 实现了以下核心能力:

  1. 命名服务:提供类似文件系统的层次化命名空间,用于存储和检索数据
  2. 配置管理:集中管理分布式系统的配置信息,支持动态更新
  3. 分布式同步:提供分布式锁、屏障等同步原语
  4. 组服务:管理集群成员关系,实现服务发现和故障检测

ZooKeeper 的设计目标

ZooKeeper 的设计遵循以下核心原则:

简单性:ZooKeeper 提供一个共享的层次化命名空间,类似于标准文件系统的目录树结构。命名空间由数据寄存器(称为 znode)组成,类似于文件和目录。与典型的文件系统不同,ZooKeeper 数据保存在内存中,可以实现高吞吐量和低延迟。

高性能:ZooKeeper 专为高性能而设计,特别是在读多写少的工作负载中表现出色。在读取与写入比例约为 10:1 的情况下,ZooKeeper 的性能最佳。

高可用:ZooKeeper 服务通过复制机制实现高可用性。一组 ZooKeeper 服务器组成一个集群(称为 ensemble),只要大多数服务器可用,服务就能继续运行。

顺序性:ZooKeeper 对每次更新都标记一个数字,反映所有 ZooKeeper 事务的顺序。后续操作可以利用这个顺序实现更高级别的抽象,如同步原语。

ZooKeeper 与其他协调服务的对比

特性ZooKeeperetcdConsul
一致性协议ZABRaftRaft
数据模型层次化命名空间键值对键值对
语言支持Java, CGo, 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 提供以下一致性保证:

  1. 顺序一致性:客户端的更新操作按照发送顺序应用
  2. 原子性:更新操作要么成功要么失败,没有中间状态
  3. 单一系统映像:无论连接到哪个服务器,客户端看到的服务视图相同
  4. 可靠性:更新一旦被应用,就会持久保存直到被覆盖
  5. 时效性:客户端的系统视图在一定时间范围内保证是最新的

ZooKeeper 架构

┌─────────────────────────────────────────────────────────────┐
│ ZooKeeper 集群架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 客户端层 │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Client1 │ │ Client2 │ │ Client3 │ │ Client4 │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ └───────┼───────────┼───────────┼───────────┼────────┘ │
│ │ │ │ │ │
│ └───────────┴─────┬─────┴───────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ZooKeeper 服务端 │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Leader │ │ Follower │ │ Follower │ │ │
│ │ │ (读写请求) │ │ (读请求) │ │ (读请求) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ 内存数据库 │ │ 内存数据库 │ │ 内存数据库 │ │ │
│ │ │ 事务日志 │ │ 事务日志 │ │ 事务日志 │ │ │
│ │ │ 快照文件 │ │ 快照文件 │ │ 快照文件 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │ │ │ │
│ │ └────────────────┴────────────────┘ │ │
│ │ ZAB 协议 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

组件说明

Leader(领导者)

  • 处理所有写请求
  • 负责事务的发起和投票
  • 维护集群状态

Follower(跟随者)

  • 处理读请求
  • 参与 Leader 选举
  • 参与 write 事务投票

Observer(观察者)

  • 不参与投票
  • 只处理读请求
  • 用于扩展集群读能力

教程目录

基础入门

核心机制

客户端开发

进阶应用

知识速查

学习建议

  1. 理解原理:深入理解 ZAB 协议、会话机制、Watcher 机制
  2. 动手实践:搭建 ZooKeeper 集群,使用命令行操作
  3. 结合场景:结合实际业务场景学习,如分布式锁、配置中心
  4. 阅读源码:阅读 Curator 等客户端库的源码
  5. 关注性能:学习 ZooKeeper 的性能调优

参考资料

准备好开始学习了吗?点击下一章开始你的 ZooKeeper 学习之旅。