apache zookeeper是一种集中的服务,用于维护配置信息、命名、提供分布式同步和提供组服务。所有这些类型的服务都是通过分布式应用程序来使用的。每次执行的时候,都有大量的工作要去解决那些不可避免的bug和竞态条件。由于实现这些服务的困难,应用程序最初通常会对它们进行节省,这使得它们在出现更改时变得很脆弱,并且难于管理。即使完成了正确的工作,这些服务的不同实现在部署应用程序时也会导致管理的复杂性。
1、zookeeper:分布式应用程序的分布式协调服务
zookeeper是分布式的分布式应用程序的分布式协作服务。它暴露了一组简单的原语,这些原语是分布式应用程序可以构建的,用于实现更高级别的同步、配置维护、组和命名。它被设计为易于编程,并且使用了一个以熟悉的目录树结构的文件系统结构为特征的数据模型。它在Java中运行,并且具有Java和c的绑定。
众所周知,协调服务是很难得到正确的。他们特别容易出错,比如种族状况和死锁。zookeeper的动机是为了减轻分布式应用程序的责任,这些应用程序需要从头开始执行协调服务。
2、设计目标
zookeeper is simple(Zookeeper很简单)。zookeeper允许分布式进程通过共享的层级名称空间进行协调,该名称空间与标准文件系统类似。名称空间由数据寄存器组成,在动物园管理员的说法中称为znode,它们类似于文件和目录。与典型的用于存储的文件系统不同,zookeeper的数据保存在内存中,这意味着动物园管理员可以实现高吞吐量和低延迟数。
zookeeper的实现对高性能、高可用性、严格的访问权限提供了额外的保证。zookeeper的性能方面意味着它可以在大型的分布式系统中使用。可靠性方面的因素使它不会成为一个单一的失败点。严格的排序意味着可以在客户机上实现复杂的同步原语。
ZooKeeper is replicated(Zookeeper是复制).就像它所协调的分布式过程一样,动物园管理员自己也打算在一组被称为集合的主机上进行复制。
ZooKeeper Service
组成zookeeper服务的服务器之间必须相互了解。它们维护内存中的状态映像,以及持久性存储中的事务日志和快照。只要大部分服务器都可用,zookeeper就可以使用了。
客户端连接到一个Zookeeper服务器。客户端维护一个TCP连接,通过它发送请求、获得响应、获得观察事件和发送心跳。如果与服务器的TCP连接中断,客户端将连接到另一个服务器。
ZooKeeper is ordered(Zookeeper是有序的)。Zookeeper用一个数字来记录每一个更新,这个数字反映了所有动物管理员的交易的顺序。后续操作可以使用该顺序来实现更高级别的抽象,例如同步原语。
ZooKeeper is fast(Zookeeper很快),它在“读占主导”的工作负载中特别快。Zookeeper应用程序运行在数千台机器上,在读取比写操作更常见的地方(10:1左右),它的执行效果最好。
3、数据模型和层次命名空间
Zookeeper提供的名称空间与标准文件系统非常相似。名称是由斜杠(/)分隔的路径元素序列。Zookeeper的名字空间中的每个节点都是通过一条路径来确定的。
ZooKeeper’s Hierarchical Namespace
4、节点和临时节点
与标准文件系统不同的是,Zookeeper命名空间中的每个节点都可以有与之关联的数据和子节点。这就像拥有一个文件系统,允许文件也可以是一个目录。(Zookeeper被设计用来存储协调数据:状态信息、配置、位置信息等,所以存储在每个节点的数据通常很小,在字节到千字节范围内。)我们使用znode这个术语来说明我们正在讨论的是Zookeeper的数据节点。
znode维护一个统计结构,其中包括数据更改的版本号、ACL更改和时间戳,以允许缓存验证和协调更新。每当一个znode的数据发生变化时,版本号就会增加。例如,每当客户端检索数据时,它也会接收数据的版本。
存储在一个名称空间中的每个znode上的数据被原子地读取和写入。读取与znode相关联的所有数据字节,而写入将替换所有数据。每个节点都有一个访问控制列表(ACL),它限制了谁可以做什么。
Zookeeper也有“临时节点”的概念。只要创建znode的会话是活动的,这些znode就存在。当会话结束时,znode将被删除。当您想要实现tbd时,临时节点是有用的。
5、条件更新和Watch
Zookeeper支持Watch的概念。客户端可以在znode上设置一个Watch。当znode改变时,Watch将被触发和移除。当一个Watch被触发时,客户端收到一个包,它说znode已经改变了。如果客户端和Zookeeper服务器之间的连接被破坏,客户端将收到一个本地通知。这些可以用于 [tbd]。
6、Guarantees
Zookeeper的速度非常快,非常简单。然而,由于它的目标是为更复杂的服务的构建提供基础,比如同步,它提供了一组保证。这些都是:
- 顺序一致性 - 来自客户端的更新将按照发送的顺序应用。
- 原子性 - 更新要么成功,要么失败。没有部分结果。
- 单个系统映像 - 客户端将看到服务的相同视图,而不管它连接到的服务器是什么。
- 可靠性 - 一旦应用了更新,它就会一直保持下去,直到客户端改写更新。
- 低延时 - 系统的客户端视图保证在一定时间内是最新的。
有关这些信息的更多信息,以及如何使用它们,请参阅[tbd]。
7、Simple API
create : 在树的一个位置创建一个节点
delete:删除一个节点
exists:检测当前目录是否有一个节点
get data:读取一个节点的数据
set data:把数据写入到节点
get children:检索一个节点下的所有子节点
sync:等待数据被传播
更深入地讨论这些问题,以及如何使用它们来实现更高级别的操作,请参阅tbd
8、实现
Zookeeper组件显示了Zookeepe服务的高级组件。除了请求处理器之外,每个组成Zookeepe服务的服务器都复制自己的每个组件的副本。
ZooKeeper Components
复制的数据库是一个包含整个数据树的内存数据库。更新被记录到磁盘以恢复可恢复性,并且在将其应用到内存数据库之前将其序列化为磁盘。
每个Zookeeper服务器服务客户端。客户端连接到一个服务器来提交请求。读取请求由每个服务器数据库的本地副本提供服务。请求更改服务状态,编写请求,由协议协议处理。
作为协议协议的一部分,所有来自客户端的请求都被转发到一个名为“leader”的服务器上。Zookeeper服务器的其余部分,称为“followers”,接收来自领导者的消息建议,并就消息传递达成一致。消息传递层负责在失败中替换领导者,并将追随者与领导者同步。
Zookeeper使用自定义的原子消息传递协议。由于消息传递层是原子的,所以Zookeeper可以保证本地副本不会出现差异。当领导收到一个写请求时,它会计算出要应用的写操作时系统的状态,并将其转换为捕获这个新状态的事务。
9、Performance
Zookeeper的设计是非常高效的。但真的是这样吗?动物园管理员的开发团队在yahoo!研究表明它是。(请参阅管理员吞吐量,因为读写比率不同。)在读取数量超过写操作的应用程序中,它的性能特别高,因为写操作涉及到同步所有服务器的状态。(对于协调服务来说,读取输出是典型的情况。)
ZooKeeper Throughput as the Read-Write Ratio Varies
当读写比率变化时,动物园管理员的吞吐量是一个吞吐量图,它在服务器上运行3.2,在服务器上有2Ghz的Xeon和两个SATA 15K RPM驱动器。其中一个驱动器被用作一个专用的Zookeeper日志设备。这些快照被写入操作系统驱动器。写请求是1K写的,读的是1K读。“服务器”显示了动Zookeeper的整体规模,以及组成该服务的服务器数量。大约有30个服务器被用来模拟客户端。Zookeeper的整体配置是这样的:Leader不允许来自客户的连接。
基准测试也表明它是可靠的。在出现错误时的可靠性显示了部署对各种故障的响应。
10、可靠性
为了展示系统的行为随着时间的推移,我们运行了一个由7台机器组成的Zookeeper服务。我们和以前一样运行了相同的饱和基准,但是这次我们将写百分比保持在30%不变,这是我们预期工作负载的保守比率。
Reliability in the Presence of Errors
从这张图中我们可以得到一些重要的观察结果。首先,如果Follers失败并迅速恢复,那么即使失败,Zookeeper也能够保持高的吞吐量。但更重要的是,领导选举算法允许系统快速恢复,以防止吞吐量大幅下降。在我们的观察中,Zookeeper只需要不到200毫秒就能选出一位新Leader。第三,随着Follers的恢复,当他们开始处理请求时,ZooKeeper可以再次提高吞吐量。
11、The ZooKeeper Project
ZooKeeper已经成功地应用于许多工业应用。它在yahoo!作为雅虎的协调和故障恢复服务。Message Broker,它是一个高度可伸缩的发布-订阅系统,管理数千个用于复制和数据交付的主题。它被yahoo!的抓取服务使用。爬行器,它也管理故障恢复。大量的Yahoo !广告系统也使用ZooKeeper来实现可靠的服务。