概述
Apache ZooKeeper 是 Google Chubby 项目的开源实现,其曾作为 Hadoop 的子项目,在大数据领域被广泛应用。Zookeeper 受到文件系统 API 的启发,提供了一组简易的 API,让开发人员能够达成通用的协作任务,涵盖选举主节点、管理组内成员关系、管理元数据等方面。
适用的场景
在分布式系统中存在多种协作任务的情况。例如:
- 典型的主-从工作模式,当从节点处于空闲状态时,会通知主节点可以接受工作;或者在没有主节点的情况下,许多节点需要选举出一个主节点。
- 分布式锁
- 元数据存储,由于 ZK 的顺序访问、全部数据放在内存等设计,ZK 也被很多系统用作元数据存储。著名的依赖 ZK 的开源项目有 Apache HBase、Apache Kafka、Apache HDFS、ClickHouse、Apache Flink 等。
不适用的场景
- 不适用于海量数据存储,尽管可视为强一致的 KV 存储。在设计系统时,应将协同元数据与应用数据区分开来。
- 不适于进行过细粒度的锁操作,分布式锁若过细会给服务器端带来巨大压力,业务也会非常不稳定。
注意事项
- 设计系统时应当考虑 ZK 短暂不可用的情形,否则 ZK unavailable 的影响将会放大许多倍。ZK 不可用的情况众多:多数节点的硬件/软件故障,节点间的网络隔离/延迟增高,client-server 间的网络隔离/延迟增高等。
- 一旦数据量超出 1GB,就应当思考将 ZK 用作元数据存储是否正确。
- 一旦单系统内锁的粒度细化到多于 1000 个锁或多于 100 个 client 争抢一个锁,就应当思考将 ZK 用作粗粒度锁是否正确。
- zk 参数
jute.maxbuffer
限制了请求包的 size,当前默认 1MB,如果一个 znode 下的 children 过多,.getChildren()
返回时可能会超出这个限制,进而报错。如有需求,应首先思考 zk 的使用方式是否正确,例如单个 znode 的 children 过多或单个 znode 的数据量过大等。确实有需求,可以适当增大(client 和 server 都需要设置)。

- 另外,为保证集群中组件的稳定性,不建议用户使用 ZK 自主编程