一、简介
ZooKeeper是一个高性能,分布式的,开源分布式应用协调服务。它提供了简单原始的功能,分布式应用可以基于它实现更高级的服务,比如同步,集群管理,命名空间,配置维护等。ZooKeeper使用了我们熟悉的文件树状结构作为自己的数据模型,因此是易于使用的。
我们知道,由于资源竞争等因素的影响,维护分布式服务的正常运行是一项极具挑战的事情。图1形象地说明了道路交通中没有信号灯的指挥协调导致出现交通阻塞混乱的情况出现。对于分布式系统来说,如果没有一个协调者的角色对各个分布式应用进行协调,分布式系统同样会出现一团糟的情况。
图1:混乱的交通
ZooKeeper背后的动机则是为了简化分布式应用的开发流程,并提供更加敏捷健壮的方案,以此来协调分布式系统中的各个应用服务。可以使用交通信号灯来形象比喻zk在分布式系统中的作用。
图2:交通信号灯对交通进行协调
二、特点
总体来说,ZooKeeper具有以下的特点。
1. 简单
ZooKeeper使用了类似文件系统的数据模型,即每个节点按照层级的关系组成了ZooKeeper的命名空间。一个ZooKeeper的命名空间示例如下:
图: ZooKeeper的层级命名空间
上图包含了五个节点(在ZooKeeper中称为znode,znode并不等于机器,实际中我们可以用znode表示分布式应用的一个进程),可以用它的路径来表示这些节点,例如/app1,/app1/p_2,等。
znode节点可以包含数据,也可以不包含。如果一个znode包含数据,那么数据被存储为字节数组(byte array)。字节数组的格式取决于我们自己的解析,使用可以使用Protocol Buffers,MessagePack等序列化。
为了操作znode,你仅需要使用以下的API。
- create /path data
创建一个名为/path的znode节点,并包含数据data - delete /path
删除名为/path的znode - exists /path
检查是否否在名为/path的znode - getData /path
返回名为/path的znode的数据 - setData /path data
设置名为/path的znode的数据为data - getChildren /path
返回/path节点下所有子节点列表
2. 多点
图: ZooKeeper服务架构
作为分布式应用的协调者,ZooKeeper要保证自己本身的高可用特性。为了达到这个目的,ZooKeeper跟其他分布式应用一样,被设计成多点的服务,以避免单点故障。客户端连接其中一个ZooKeeper进程,不同的ZooKeeper进程会进行同步的操作。
3. 有序
ZooKeeper使用一个数字来标识一个更新操作,以反映ZooKeeper事务的顺序特性。基于这一特性,ZooKeeper可以实现更新高级的抽象操作,例如同步等。
4. 快速
无论是读写操作,ZooKeeper可以实现快速响应。尤其对于读操作,ZooKeeper可以达到更快的响应速度。
三、保证
ZooKeeper简单且快速响应,它的目的是为构建复杂的分布式应用而服务,例如为分布式系统提供同步管理,集群管理等。为了达到这一目的,ZooKeeper提供以下的保证:
- 顺序一致性
ZooKeeper提供了顺序保障,这意味着同一个会话中的请求会以FIFO(先进先出)顺序执行。通常,一个客户端只打开一个会话,因此客户端请求将全部以FIFO顺序执行。
如果客户端拥有多个并发的会话,FIFO顺序在多个会话之间未必能够保持。而即使同一个客户端中连贯的会话并不重叠,也未必能够保证FIFO顺序。 - 原子性
一个操作或者成功,或者失败,不会出现部分成功的结果 - 单一系统映像
虽然ZooKeeper本身以多点的形式运行,但对于客户端来说,无论连接的是哪个server进程,看到的是同样的视图。 - 可靠性
一旦更新操作被执行,更新的操作就会被持久化,直到被下一次更新覆盖。 - 时效性
客户端看到的系统视图在一定的时间范围内总是最新的。
参考资料
- https://zookeeper.apache.org/doc/trunk/zookeeperOver.html
- 《ZooKeeper分布式过程协同技术详解》,Flavio Junqueira等著,谢超等译