Zookeeper总览(翻译自Zookeeper官方网站Release 3.4.11版本)

Zookeeper


Zookeeper:一个为分布式应用设计的分布式协调服务

ZooKeeper是一款开源的分布式应用分布式协调服务。它包含一个简单的原语集,分布式应用程序能够基于它实现同步服务,配置维护和命名服务等。Zookeeper 设计很容易进行编程,它使用一种相似于文件系统的目录树结构的数据模型,以 java 方式运行,有 java 和 c 的绑定(binding)。html

协调服务是很是难以被正确实现的。他们特别容易产生诸如竞态条件、死锁等错误。ZooKeeper背后的动机是为分布式应用程序减轻从零开始实现协调服务的难度。java

设计目标

Zookeeper是很是简单的。

ZooKeeper容许分布式进程经过与标准文件系统相似组织的共享层级命名空间来相互协调。命名空间被称为znode的数据记录组成,用ZooKeeper的说法,这些记录和标准文件系统中的文件和目录很是类似。与典型的用于存储的文件系统不一样,ZooKeeper数据保存在内存中,这意味着ZooKeeper能够实现高吞吐量和低延迟。node

Zookeeper的实现着重于高性能、高可用性和严格的顺序访问。ZooKeeper的性能方面意味着它能够用于大型分布式系统。可靠性方面使它不会形成单点故障。严格的排序意味着能够在客户端实现复杂的同步原语。算法

Zookeeper 是复制的(replicated)

就像它协调的分布式进程同样,Zookeeper 自身也在被称为“ensemble”的一组主机之间进行复制。 数据库

组成 Zookeeper 服务(Service)的每一个服务器(server)之间都必须相互了解对方。他们维护一个内存状态图,以及一个持久存储的事务日志和快照。只要这些服务器(servers)中大多数是可用的,整个ZooKeeper服务就是可用的。

客户端(client)链接到任意一台ZooKeeper服务器。客户端维护一个TCP链接,经过它发送请求、获取响应、获取监视事件以及发送心跳。若是到服务器的TCP链接中断,客户端将链接到其余不一样的服务器。apache

Zokeeper是有顺序的

ZooKeeper使用反映全部ZooKeeper事务顺序的数字来标记每一个更新。后续操做可使用该次序来实现更高级别的抽象,例如同步原语。编程

ZooKeeper 是快速的

在应对以“读”为主的负载时尤为地快速。ZooKeeper应用程序在数千台机器上运行,而且在读取比写入更为广泛的状况下,性能表现最佳,比例约为10:1。缓存

Zookeeper数据模型和层级命名空间

ZooKeeper提供的命名空间与标准文件系统很是类似。路径是由斜杠/分隔的一系列元素。 ZooKeeper命名空间中的每一个节点都由一个路径标识。 服务器

Zookeeper默认节点临时节点

与标准文件系统不一样的是,ZooKeeper命名空间中的每一个节点均可以拥有与其相关的数据以及子节点。这就像一个文件系统中能够存在一个文件或一个目录。ZooKeeper被设计用来存储相关的协调数据,如状态信息、配置、位置信息等等,因此每一个节点上存储的数据一般都很小,在字节(byte)到千字节(kb)范围内。咱们使用术语znode来清楚地说明咱们正在讨论ZooKeeper数据节点。分布式

Znode 维护了一个状态(stat)结构,其中包含了表示数据改变、访问控制列表(ACL)改变的版本号、时间戳,可用于缓存校验、协调更新。每当一个znode的数据发生变化,版本号就会增长。例如,每当客户端检索数据时,客户端也会接收到相应数据的版本信息。

存储在命名空间中每一个节点上的数据是以原子方式读取和写入的。读取一个znode将得到其所有的数据,而写入则替换其所有的数据。

ZooKeeper也有临时节点的概念。当建立临时节点的客户端会话一直保持活动,瞬时节点就一直存在。而当会话终结时,瞬时节点被删除。

Zookeeper条件更新监视(watches)

ZooKeeper 支持“监视”(watches)的概念。客户端能够在znode上设置一个监视(watch)。当 znode改变时,监视(watch)将被触发并移除。当监视(watch)被触发时,当“监视”被触发时,客户端会收到一个描述了 znode 的变动的数据包。若是客户端和Zookeeper服务器之间的链接断开时,客户端将会收到一个本地通知。

Zookeeper保证(Guarantees)

Zookeeper很是地快速也很是简单。不过,因为它的目标是做为构建诸如“同步”这类更复杂服务的基础,它提供了一些的一组保证:

  • 顺序一致性 - 来自客户端的更改请求将会按照它们的发送的顺序被应用。
  • 原子性 - 更改要么成功,要么失败,不会存在部分红功、部分失败的结果。
  • 单一系统映像 - 客户端会看到 Zookeeper 服务的相同的视图,而不管它们连到具体哪个服务器上
  • 可靠性 - 一旦一次更改请求被应用,更改的结果就会被持久化,直到被下一次更改覆盖。
  • 及时性 - 客户端看到的系统视图在必定的时间范围内老是最新的。

简单的API

ZooKeeper的一个设计目标是提供一个很是简单的编程接口。 所以,它只支持这些操做:

  • create

    在(命名空间)树的一个特定地址上建立一个节点。

  • delete

    删除一个节点。

  • exists

    判断某个路径下是否存在该节点。

  • get data

    获取节点的数据。

  • set data

    向节点写入数据。

  • get children

    检索节点的子节点列表。

  • sync

    等待数据传播完成。

Zookeeper实现原理

ZooKeeper Components 显示了ZooKeeper服务的高级组件。除Request Processor外,构成ZooKeeper服务的每一个服务器都复制每一个组件的副本。

replicated database是一个内存数据库,它包含了整颗数据树。数据写入在应用到内存数据库以前,会先序列化到磁盘。

每个 Zookeeper 服务器都向客户端提供服务,客户端链接到一个确切的Zookeeper服务器提交请求。读请求从服务器数据库的本地拷贝中获取。改变Zookeeper服务状态的请求、写入请求经过一个一致性协议进行处理。

做为协议的一部分,客户端的全部写入请求都被转发到一个单独的服务器,该服务器被称为 leader。而其他的服务器,被称为follower,从leader接收消息提案(proposal)并对消息的交付取得一致。消息层维护leader失效时的更新替换以及leader和follower之间的同步。

Zookeeper 使用自定义的原子消息协议。因为消息层是原子的,Zookeeper能够保证本地的复制品不会不一致。当 leader收到一个写入请求时,它计算系统所处的状态以及什么时候应用写入请求,并将此转换为一个事务,包含新的状态。

使用

Zookeeper 的编程接口特地地定义得很简单。然而,经过这些编程接口能够更高阶的操做,例如同步原语,成员分组,全部权,等等。

性能

Zookeeper 被设计为高性能。但实际是否如此呢?在雅虎研发中心的 Zookeeper 开发团队的研究结果代表的确如此。(参见下图:Zookeeper 吞吐量随读写比的变化)。在“读”多于“写”的应用程序中尤为地高性能,由于“写”会致使在全部的服务器间同步状态。(“读”多于“写”是协调服务的典型场景。)

Zookeeper 吞吐量随读写比的变化

图“Zookeeper 吞吐量随读写比的变化” 是 Zookeeper3.2 版本运行于 Dual 2Gh Xeon + 2 个 15K RPM 的 SATA 硬盘驱动器的服务器上的结果。一个驱动器用做 Zookeeper 专用的日志设备。快照写到操做系统驱动器。写请求是 1K 数据的写入而读请求是 1K 的数据读取。“Servers”标出了 Zookeeper Ensemble 的大小,即组成 Zookeeper 服务的服务器的数量。大约30台其它的服务器被用做模拟客户端。Zookeeper Ensemble 被配置为不容许客户端链接到 Leader 。

注:3.2版本的读/写性能相对于3.1版本之前有最多达2倍的提高。

基准测试也代表了 Zookeeper 的可靠性。图“错误发生的状况下的可靠性”展现了 Zookeeper 是如何应对各类不一样的失效的。图中标注的事件以下:

  1. 一个 Follower 失效而后恢复。

  2. 另外一个不一样的 Follower 失效而后恢复。

  3. Leader 失效。

  4. 两个 Follower 失效而后恢复。

  5. 另外一个 Leader 失效。

可靠性

从这张图中能够获得几点重要的结果。首先,若是 follower 失效并快速恢复,Zookeeper 可以维持高吞吐量,尽管存在失效。但也许更重要的是,leader选举算法使系统足够快地恢复,避免了吞吐量的整体降低。从观察结果来看,Zookeeper花了不到200毫秒的时间选举出了一个新的 leader。第三,只要follower恢复,Zookeeper的吞吐量可以再次上升到刚开始处理请求时的水平。

关于ZooKeeper项目

Zookeeper 已经被成功地用在许多工业级的应用。在雅虎,Zookeeper被用做雅虎消息中间件的协调和失效恢复服务,该系统是一个高伸缩性的发布订阅系统,管理着成千上万的主题复制和数据分发。Zookeeper还被用在雅虎爬虫的抓取服务上,用于管理失效恢复。许多雅虎的广告系统也用 Zookeeper 实现可靠的服务。