分布式系统的管理员-Zookeeper

在Hadoop生态中,许多组件都以一个动物的形象来表示,唯独Zookeeper是一个管理员的形象,可见Zookeeper在hadoop生态圈中的地位,那么Zookeeper作为一个管理员,它究竟是什么?做了哪些工作?本文将做一个简单的介绍,权当是抛砖引玉。

Zookeeper简介


Zookeeper:分布式应用程序的分布式协调服务

ZooKeeper是用于分布式应用程序的分布式、开源协调服务。是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它公开了一组简单的原语,分布式应用程序可以基于这些原语来实现用于同步,配置维护以及组和命名的更高级别的服务。它的设计简单,API也简单易用,并使用了按照文件系统熟悉的目录树结构样式的数据模型。它以Java运行,并且具有Java和C的绑定。

设计目标

ZooKeeper很简单。ZooKeeper允许分布式进程通过共享的namespace相互协调,该命名空间的组织方式类似于标准文件系统。namespace由数据寄存器(在ZooKeeper看来是znode)组成,它们类似于文件和目录。与存储于磁盘的典型文件系统不同,ZooKeeper数据保留在内存中,这意味着ZooKeeper可以实现高吞吐量和低延迟。

ZooKeeper的目标是实现高性能,高可用性,严格有序的节点访问。ZooKeeper的高性能意味着它可以在大型的分布式系统中使用。可靠性方面使它不会成为单点故障。严格排序意味着可以在客户端上实现严格的同步。

Zookeeper的架构

zookeeper
Zookeeper集群是一个基于主从复制的高可用集群,组成ZooKeeper服务的服务器都必须彼此了解。它们维护内存中的状态视图,以及持久存储中的事务日志和快照。只要大多数服务器可用,ZooKeeper服务将可用。每个服务器承担如下三种角色中的一种,

  • Leader :一个Zookeeper集群同一时间只会有一个实际工作的Leader,它会发起并维护与各Follwer及Observer间的心跳。所有的写操作必须要通过Leader完成再由Leader将写操作广播给其它服务器。
  • Follower :一个Zookeeper集群可能同时存在多个Follower,它会响应Leader的心跳。Follower可直接处理并返回客户端的读请求,同时会将写请求转发给Leader处理,并且负责在Leader处理写请求时对请求进行投票。
  • Observer :Observer角色与Follower类似,但是无投票权。

客户端连接到单个ZooKeeper服务器。客户端维护一个TCP连接,通过它发送请求,获取响应,获取监视事件并发送心跳。如果与服务器的TCP连接断开,则客户端将连接到其他服务器。


分层命名空间

ZooKeeper提供的名称空间与标准文件系统的名称空间非常相似。是由斜杠'/'分隔的一系列路径元素。ZooKeeper名称空间中的每个节点都由路径标识。
分层命名空间

数据模型

与标准文件系统不同,ZooKeeper命名空间中的每个节点都可以具有与其关联的数据以及子节点。就像拥有一个文件系统一样,该文件系统也允许文件成为目录。(ZooKeeper旨在存储协调数据:状态信息,配置,位置信息等,因此存储在每个节点上的数据通常很小,一般小于1MB。)我们使用术语znode来表示在ZooKeeper中数据节点。

Znodes维护一个统计信息结构,其中包括一个用于数据更改,ACL更改和时间戳的版本号,以允许进行缓存验证和协调更新。znode的数据每次更改时,版本号都会增加

原子地读取和写入存储在名称空间中每个znode上的数据。读取将获取与znode关联的所有数据字节,而写入将替换所有数据。每个节点都有一个访问控制列表(ACL),用于限制谁可以执行操作。

ZooKeeper还具有临时节点的概念。只要创建znode的session处于活动状态,这些znode就存在。session关闭时,将删除znode。


有条件的update和watch

ZooKeeper支持watch操作。客户端可以在znode上设置一个watcher。znode进行update操作时,将触发并删除watcher(所以通常需要进行回调)。触发watcher后,客户端会收到一条消息,提示znode已更改。这个更改不一定能成功,只有超过半数server上的znode更新成功时,才视为更新成功。


特性

ZooKeeper非常快速且非常简单。其目标是作为构建更复杂的服务(例如同步)的基础,因此它提供了一组特性来实现这个目标。这些是:

  • 顺序一致性:来自客户端的更新将按照发送的顺序应用。
  • 原子性:更新成功或失败。没有部分结果。
  • 单个系统映像:无论客户端连接到哪个服务器,客户端都将看到相同的服务视图。
  • 可靠性:应用更新后,此更新将一直持续到客户端覆盖更新为止。
  • 及时性:确保系统的客户视图在特定时间范围内是最新的。

简单的API

ZooKeeper的设计目标之一是提供一个非常简单的编程界面。因此,它仅支持以下操作:

  • create:在树中的某个位置创建一个节点。

  • delete:删除节点。

  • exists:测试节点是否存在于某个位置。

  • get data:从节点读取数据。

  • set data:将数据写入节点。

  • get children:获取节点子节点的列表。

  • sync:等待数据传播。


写请求

写请求
通过Leader进行写操作,主要分为五步:

  1. 客户端向Leader发起写请求。
  2. Leader将写请求以Proposal的形式发给所有Follower并等待ACK。
  3. Follower收到Leader的Proposal后返回ACK。
  4. Leader得到过半数的ACK(Leader对自己默认有一个ACK)后向所有的Follower和Observer发送Commmit。
  5. Leader将处理结果返回给客户端。

注意

  • Leader并不需要得到Observer的ACK,即Observer无投票权。
  • Leader不需要得到所有Follower的ACK,只要收到过半的ACK即可,同时Leader本身对自己有一个ACK。上图中有4个Follower,只需其中两个返回ACK即可,因为(2+1) / (4+1) > 1/2。
  • Observer虽然无投票权,但仍须同步Leader的数据从而在处理读请求时可以返回尽可能新的数据。

读请求

读请求
读请求相比于写请求要简单得多,Leader/Follower/Observer都可直接处理读请求,从本地内存中读取数据并返回给客户端即可。


性能

ZooKeeper被设计为具有高性能。下图是Yahoo的ZooKeeper开发团队的结果。研究表明确实如此。在读取次数超过写入次数的应用程序中,该性能尤其出色,因为写入涉及同步所有服务器的状态。(对于协调服务,通常情况下,读取次数多于写入次数。)
读性能

可靠性

ZooKeeper的高可靠性在于它能在leader节点宕机的情况下,立即选出新的节点并重新提供服务,下图是由7台ZooKeeper节点组成的集群的测试结果。
可靠性
该图有一些重要的结果。

  • 首先,如果follower失败并迅速恢复,则ZooKeeper能够在失败的情况下维持高吞吐量。

  • 其次,leader选择算法允许系统恢复得足够快,以防止吞吐量大幅下降。根据开发人员的观察

  • ZooKeeper只需不到200毫秒即可选出新的leader。随着follower的恢复,ZooKeeper开始处理请求时就能够再次提高吞吐量。



参考资料:
https://www.jianshu.com/p/def486f10dc4
http://zookeeper.apache.org/doc/r3.5.7/zookeeperOver.html#zkPerfRW

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值