1. 什么是 zookeeper ?
zookeeper 是一个开源的分布式应用的协同服务
zookeeper 的设计目标是对复杂易错的分布式应用的协同操作进行抽象和封装:
- 简单的数据模型
- 集群
- 顺序访问
- 高性能
zookeeper 的特性:
- 顺序一致性,zookeeper 的对于客户端的请求,严格按照发起顺序进行处理
- 原子性,事务性请求的原子性,要么全部失败,要么全部成功
- 可靠性,一定事务请求成功,集群所有节点对于该请求的后续响应都是一致性,除非有其他请求进行修改
- 实时性,从 zookeeper 集群节点获取的数据都是最新的
- 单一视图,从 zookeeper 集群节点获取的数据始终是一致的
2. zookeeper 提供哪些服务?
应用程序要使用 zookeeper ,需要引入对应的 zookeeper 客户端
zookeeper 典型的应用场景:
- 统一配置管理
- 统一命名服务
- DNS 服务
- 组成员管理(主从管理、负载均衡)
- 分布式锁的实现
zookeeper 更适用来存储一些关键数据,如配置文件、应用状态等,不适用于较大的数据量的存储
实际示例:
- Hadoop:使用 zookeeper 做 Namenode 的高可用
- HBase:通过 zookeeper 保证集群中只有一个 master,保存集群中的 RegionServer 列表、保存 hbase:meta 表的位置
- Kafka:集群成员管理,controller 节点的选举
3. zookeeper 的数据模型
zookeeper 的数据模型是层次模型,类似于标准的文件系统
为什么使用层次模型而不是 K-V 模型:
- 层次模型的树形结构更容易表达数据之间的层次关系
- 层次模型的树形结构便于为不同的应用分配独立的命名空间
zookeeper 的层次模型的每个节点称为 znode,每个 znode 都可以保存数据(这是和文件系统的区别)
图示:
zookeeper 对外提给了一个简化的类文件系统的 API 来访问 znode:
- znode 以 UNIX 风格的路径进行命名,以
/进行分隔 - znode 除了保存的数据,还以Key-Value 的形式保存了相关的版本信息等状态属性
- znode 的所有操作都是 wait-free,就是正执行的操作不影响其他 API
- znode 最多存储 1 MB 的数据
znode 的状态属性:
| Key | -- |
|---|---|
| cZxid | znode 创建时的事务 ID |
| ctime | znode 创建的时间 |
| mZxid | 最后修改 znode 的事务 ID |
| mtime | 最后修改 znode 的时间 |
| pZxid | 表示该节点的子节点列表最后一次修改的事务 ID |
| cversion | 子节点版本号,子节点每次修改版本号加1 |
| dataversion | 数据版本号,数据每次修改该版本号加1 |
| aclversion | 权限版本号,权限每次修改该版本号加1 |
| ephemeralOwner | 创建该临时节点的会话的sessionID |
| dataLength | 该节点的数据长度 |
| numChildren | 直接子节点的数量 |
pZxid:只有子节点的创建或者删除才会变更该值
ephemeralOwner:如果是持久性节点,这个值为 0
znode 的划分
znode 可以是永久性的,也可以是临时性的:
- 永久性的 znode(PERSISTENT)在创建后即时 zookeeper 宕机或者 client 会话结束也不会丢失
- 临时性的 znode(EPHEMERAL)如果 zookeeper 或者 client 会话结束后就会丢失
znode 也可以是顺序性,顺序性的 znode 关联一个唯一的 单调递增整数作为后缀或者命名:
- 永久性的顺序 znode(PERSISTENT_SEQUENTIAL),具有顺序性的永久 znode
- 临时性的顺序 znode(EPHEMERAL_SEQUENTIAL)
znode 主要划分为上面四种
4. znode 的简单API
通过 zkCli 可以对 zookeeper 进行一些简单操作:
| 命令 | 作用 |
|---|---|
| help | 可以展示 zkCli 支持的命令 |
| ls | 展示 zookeeper 下的 znode,参数 -R 表示向下递归 |
| ls2 | 同 ls 命名,但是展示的数据更多 |
| get | 获取 znode 的数据和状态信息 |
| stat | 获取 znode 的状态信息数据 |
| create | 创建 znode 并赋值,-e 表示创建的 znode 是临时性的,-s表示是顺序性的 |
| set | 修改 znode 的数据 |
| delete | 删除 znode |