译自http://zookeeper.apache.org/doc/trunk/zookeeperOver.htmlhtml
ZooKeeper是一个用于分布式应用的开源分布式协调服务。它提供了简单的原语集合,分布式应用可在这些原语之上构建用于同步、配 置维护、分组和命名的高层服务。ZooKeeper的设计使得编程容易,而且使用相似于普遍熟知的文件系统目录树结构的数据模型。它运行在Java环境 中,可是有Java和C语言绑定。node
分布式协调服务是出了名的可贵编写正确,很容易出现竞争条件和死锁之类的错误。ZooKeeper的动机是减轻为分布式应用开发协调服务的负担。算法
ZooKeeper让分布式进程可经过共享的、与标准文件系统相似的分层名字空间相互协调。名字空间由数据寄存器(在ZooKeeper世界中称做znode)构成,这与文件和目录相似。与用于存储设备的典型文件系统不一样的是,ZooKeeper在内存中保存数据,这让其能够达到高吞吐量和低延迟。数据库
ZooKeeper的实现很重视高性能、高可用性,以及严格的顺序访问。高性能意味着可将ZooKeeper用于大的分布式系统。可靠性使之可避免单点失败。严格的顺序访问使得客户端能够实现复杂的同步原语。apache
与它所协调的进程同样,ZooKeeper自己也会试图在一组主机间进行复制,这就是集群。编程
组成ZooKeeper服务的各个服务器必须相互知道对方。它们在内存中维护状态和事务日志,还在永久存储中维护快照。只要大部分服务器可用,ZooKeeper服务就是可用的。缓存
客户端链接到单个ZooKeeper服务器。客户端维持一个TCP链接,经过这个链接发送请求、接收响应、获取观察事件,以及发送心跳。若是到服务器的TCP链接断开,客户端会链接到另外一个服务器。服务器
ZooKeeper为每次更新设置一个反映全部ZooKeeper事务顺序的序号。并发操做可以使用序号来实现更高层抽象,如同步原语。并发
在读操做为主的负载下特别快。ZooKeeper应用运行在成千上万台机器中,在读操做比写操做频繁,两者比例约为10:1的状况下,性能最好。分布式
ZooKeeper提供的名字空间与标准文件系统很是类似。名字是一个由斜杠/分隔的路径元素序列。ZooKeeper名字空间中的每一个节点都由其路径标识。
与标准文件系统不一样,ZooKeeper名字空间中的每一个节点均可以有关联的数据以及子节点。这就像一个容许文件也是目录的文件系统。 (ZooKeeper设计用于存储协调数据:状态信息、配置、位置信息等,因此一般存储在每一个节点中的数据很小,在字节到千字节范围内)讨论 ZooKeeper数据节点时,咱们用术语znode来明确指示。
Znode会维护一个stat结构体,其中包含数据和ACL的版本号与时间戳,以便于进行缓存验证和协调更新。每次修改znode数据时,版本号会增加。客户端获取数据的时候,也同时获取数据的版本。
对znode数据的读写操做是原子的。读取操做获取节点的全部数据,写入操做替换全部数据。节点的访问控制列表(ACL)控制能够进行操做的用户。
ZooKeeper具备临时节点的概念。只要建立节点的会话是活动的,临时节点就存在。一旦会话终止,临时节点会被删除。临时节点对于实现tbd是颇有用的。
ZooKeeper支持观察的概念。客户端能够在znode上设置观察。观察将在znode修改时被触发和移除。观察被触发时客户端会收到一个数据包,指示znode已经被修改。若是与ZooKeeper服务之间的链接断开,客户端会收到一个本地通知。这可用于tbd。
ZooKeeper很是高效和简单。基于其目标:成为构建如同步这样的更复杂服务的基础,ZooKeeper提供下述保证:
l 顺序一致性:客户端的更新将以请求发送的次序被应用。
l 原子性:更新要么成功,要么失败,没有部分更新。
l 单一系统镜像:不管链接到哪一个服务器,客户端将看到同样的视图。
l 可靠性:更新操做的结果将是持续的,直到客户端覆盖了更新。
l 及时性:在某个时间范围内,客户端视图确保是最新的。
关于这些保证的详细信息,以及如何使用这些保证,请参看tbd。
ZooKeeper的设计目标之一是提供很是简单的编程接口。ZooKeeper仅支持这些操做:
l create:在树中某位置建立一个节点。
l delete:删除一个节点。
l exists:测试某位置是否存在某节点。
l get data:读取节点数据。
l set data:向节点写入数据。
l get children:获取子节点列表。
l sync:等待数据传播。
关于这些操做的更深刻讨论,以及如何使用它们来实现更高层的操做,请参看tbd。
下图显示了ZooKeeper服务的高层组件。除了请求处理器(Request Processor)以外,组成ZooKeeper服务的每一个服务器拥有每一个组件的自有拷贝。
自我复制数据库(replicated database)是一个包含整个数据树的内存数据库。更新会记录到磁盘中以即可以恢复,而且将写操做应用到内存数据库以前会先写入到磁盘。
每一个ZooKeeper服务器都为客户服务。客户端链接到一个服务器,提交请求。读请求由每一个服务器数据库的本地拷贝进行服务。改变服务状态的请求和写请求由一致性协议处理。
做为一致性协议的一部分,客户端的全部写请求都被转发到单个服务器,也就是领导者。其余ZooKeeper服务器则是跟随者,它们接收来自领导者的建议,对传递的消息达成一致。消息层考虑了替换失败的领导者和跟随者与领导者同步的问题。
ZooKeeper使用定制的原子消息协议。由于消息层是原子的,ZooKeeper可保证本地拷贝不会发散(diverge)。收到写请求时,领导者计算写入操做后系统的状态,将其转换成一个捕获此状态的事务。
ZooKeeper的编程接口很是简单。可是,可将其用于实现高层顺序操做,如同步原语、组成员管理、全部者关系管理等。更多信息请参看tbd。
ZooKeeper被设计为高性能的。但它真的是高性能的吗?Yahoo研究中心的ZooKeeper开发团队证明了ZooKeeper的高性能,特别是在读操做比写操做多的应用中(见下图),由于写操做涉及在全部服务器间同步状态。(读操做比写操做可能是协调服务的典型状况)
上图是ZooKeeper 3.2在配置有两个2GHz Xeon处理器和两个SATA 15K RPM驱动器的服务器上运行时的吞吐率图形。一个驱动器配置为ZooKeeper日志专用设备。快照写入到操做系统驱动器。读写操做1KB的数据。“服务器数”指的是ZooKeeper集群的大小,即组成服务的服务器个数。大约30个其余服务器用于模拟客户端。ZooKeeper集群配置为不容许客户端链接到领导者。
提示:3.2版的读写性能是3.1版的2倍。
Benchmarks也代表ZooKeeper是可靠的。下图(第10节的图)显示了ZooKeeper在各类失败状况下的反应。图中标记的各个事件是:
1.跟随者失败和恢复
2.另外一个跟随者失败和恢复
3.领导者失败
4.两个跟随者失败和恢复
5.另外一个领导者失败
为揭示在有失败注入时系统的行为,咱们在一个由7台机器组成的ZooKeeper服务上运行和先前同样的benchmark测试,可是让写操做的百分比固定为30%,这是预期负载比例的保守估计。
此图有几处值得仔细观察。首先,若是跟随者失败后快速恢复,则ZooKeeper能够维持高吞吐率。但更重要的是,领导者选举算法让系 统能够足够快地恢复,以阻止吞吐率有实质性的降低。据咱们观察,ZooKeeper选举一个新的领导者的时间小于200ms。第三,一旦跟随者恢复而且开 始处理请求,ZooKeeper能够恢复高吞吐率。
ZooKeeper已经在不少工业应用中成功使用。 Yahoo!在Yahoo! Message Broker中使用ZooKeeper做为协调和故障恢复服务。 Yahoo! Message Broker是一个高度扩展的发布-订阅系统,管理着成千上万个须要拷贝和数据传递的话题。Yahoo!的不少广告系统也 使用ZooKeeper来实现可靠服务。
咱们鼓励用户和开发者加入社区,贡献技能。更多信息请看Apache的ZooKeeper工程。