1.基本介绍
Zookeeper是一个由多个server组成的集群,分布、开源的应用程序协调服务,符合分布式服务ACP原理中的CP。它是集群的管理者,监视着集群中各个节点的状态,根据节点的反馈进行下一步合理操作。主要解决分布式应用经常遇到的数据管理问题,一些RPC框架(如点评pigeon、阿里dubbo的早期版本)使用ZK用来做服务发现和注册,点评的配置管理组件Lion用来做配置数据的获取更新,kafka⽤于检测崩溃,实现主题(topic)的发现,并保持主题的⽣产和 消费状态。zookeeper维护一个类似文件系统的数据结构。如图:
每个子目录项都被称作为 znode,和文件系统一样,自由增加及删除,唯一不同其可存储数据,并提供节点的通知机制:客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。Znode分为四种类型
- PERSISTENT-持久化目录节点。(客户端与zookeeper断开连接后,该节点依旧存在)。
- PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点。(客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号)
- EPHEMERAL-临时目录节点(客户端与zookeeper断开连接后,该节点被删除)
- EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点。(客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号)
基于目录的锁实现:
关于ZooKeeper的功能,一个简单的例子就是通过锁来实现临界区域。 我们知道有很多形式的锁(如:读/写锁、全局锁),通过ZooKeeper来实 现锁也有多种方式。这里讨论一个简单的方式来说明应用中如何使用 ZooKeeper,我们不再考虑其他形式的锁。
假设有一个应用由n个进程组成,这些进程尝试获取一个锁。再次强 调,ZooKeeper并未直接暴露原语,因此我们使用ZooKeeper的接又来管理 znode,以此来实现锁。为了获得一个锁,每个进程p尝试创建znode,名 为/lock。如果进程p成功创建了znode,就表示它获得了锁并可以继续执行 其临界区域的代码。不过一个潜在的问题是进程p可能崩溃,导致这个锁永 远无法释放。在这种情况下,没有任何其他进程可以再次获得这个锁,整个系统可能因死锁而失灵。为了避免这种情况,我们不得不在创建这个节 点时指定/lock为临时节点。
其他进程因znode存在而创建/lock失败。因此,进程监听/lock的变化, 并在检测到/lock删除时再次尝试创建节点来获得锁。当收到/lock删除的通知时,如果进程p还需要继续获取锁,它就继续尝试创建/lock的步骤,如果 其他进程已经创建了,就继续监听节点。
监视点的羊群效应和可扩展性:
有一个问题需要注意,当变化发生时,ZooKeeper会触发一个特定的 znode节点的变化导致的所有监视点的集合。如果有1000个客户端通过 exists操作监视这个znode节点,那么当znode节点创建后就会发送1000个通 知,因而被监视的znode节点的一个变化会产生一个尖峰的通知,该尖峰可 能带来影响,例如ÿ