ZooKeeper系列:开篇介绍

336 阅读6分钟

ZooKeeper 是分布式应用程序的分布式开源协调服务。它公开了一组简单的原语,分布式应用程序可以基于这些原语实现更高级别的同步、配置维护、组和命名服务。

众所周知,协调服务很难做好。它们特别容易出现竞争条件和死锁等错误。ZooKeeper 背后的动机是减轻分布式应用程序从头开始实现协调服务的责任。

分布式应用程序可以给予它实现如数据发布/订阅,负载均衡,命名服务,分布式协调/通知,集群管理,Master选举,分布式锁和分布式队列等功能。

设计目标

zk-target

ZooKeeper 很简单: ZooKeeper 允许分布式进程通过共享的分层命名空间相互协调,该命名空间的组织方式类似于标准文件系统。命名空间由数据寄存器组成——在 ZooKeeper 用语中称为 znodes——它们类似于文件和目录。与为存储而设计的典型文件系统不同,ZooKeeper 数据保存在内存中,这意味着 ZooKeeper 可以实现高吞吐量和低延迟。

ZooKeeper 非常重视高性能、高可用性、严格有序的访问。ZooKeeper 的性能方面意味着它可以用于大型分布式系统。可靠性方面使其不会成为单点故障。严格的排序意味着可以在客户端实现复杂的同步原语。

ZooKeeper 被复制: 与它协调的分布式进程一样,ZooKeeper 本身旨在通过一组称为 ensemble 的主机进行复制。

zk-services

组成 ZooKeeper 服务的服务器必须相互了解。它们在内存中维护状态图像,以及持久存储中的事务日志和快照。只要大多数服务器可用,ZooKeeper 服务就可用。

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

ZooKeeper 组织有序: ZooKeeper在每次更新上都印上一个数字,以反映所有ZooKeeper事务的顺序。后续操作可以使用该顺序来实现更高级别的抽象,例如同步原语。

ZooKeeper 速度很快: 它在“以读取为主”的工作负载中尤其快。ZooKeeper 应用程序在数千台机器上运行,它在读取比写入更常见的情况下表现最佳,比率约为 10:1。

分层命名空间

ZooKeeper 提供的命名空间很像标准文件系统。名称是由斜杠 (/) 分隔的一系列路径元素。其命名空间中的每个节点都由路径标识。

zk-namespace

节点和临时节点

不能把zk当作数据库使用,它只是存储简单的节点,减少数据量,可以减少网络带宽和数据延迟,以提供更高的性能

与标准文件系统不同,ZooKeeper 命名空间中的每个节点都可以拥有与其关联的数据以及子节点。这就像拥有一个允许文件也成为目录的文件系统。(ZooKeeper 被设计用来存储协调数据:状态信息、配置、位置信息等,所以每个节点存储的数据通常很小,在字节到千字节的范围内。)我们使用术语znode来明确我们正在谈论 ZooKeeper 数据节点。

Znode 维护一个统计结构,其中包括数据更改、ACL 更改和时间戳的版本号,以允许缓存验证和协调更新。每次 znode 的数据更改时,版本号都会增加。例如,每当客户端检索数据时,它也会收到数据的版本。

存储在命名空间中每个 znode 的数据是原子读取和写入的。读取获取与 znode 关联的所有数据字节,写入替换所有数据。每个节点都有一个访问控制列表 (ACL),它限制谁可以做什么。

ZooKeeper 也有临时节点的概念。只要创建 znode 的会话处于活动状态,这些 znode 就存在。当会话结束时,znode 被删除。

有条件的更新和监视

ZooKeeper支持 watch 的概念。客户端可以在 znode 上设置监视。当 znode 发生变化时,watch 将被触发并移除。当 watch 被触发时,客户端会收到一个数据包,说明 znode 已更改。如果客户端和其中一个 ZooKeeper 服务器之间的连接断开,客户端将收到本地通知。

担保

ZooKeeper 非常快速且非常简单。但是,由于它的目标是成为构建更复杂服务(例如同步)的基础,因此它提供了一组担保。如图

zk-namespace

简单的 API

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

zk-namespace

zookeeper常用的场景

如下列举了zookeeper常用的几种功能实现场景

zk-reliability

高性能与可靠性

zk-performance

如上图是zookeeper 3.2版本的吞吐量随读写比的变化,“servers”表示zookeeper集合的大小,即构成服务的服务器的数量。x坐标是读写的比例,y坐标是并发的数量,当集群数大于3而且读的比例占到100%的时候 他的并发将近直线提升可以达到十几万。

为了测试可靠性,使用7台机器组装成一个集群,写入百分比保持在30%,调整不同的故障,最终的结果如下图zk-reliability

1.追随者的失败和恢复 2.不同追随者的失败和恢复 3.领袖的失败 4.两个追随者的故障和恢复 5.另一位领导者的失败

如上5种故障导致的波动如图,首先,如果followers失败并迅速恢复,那么 ZooKeeper 能够在失败的情况下维持高吞吐量。但更重要的是,leader选举算法允许系统足够快地恢复,以防止吞吐量大幅下降。在我们的观察中,ZooKeeper 用不到 200 毫秒的时间来选举一个新的领导者。而随着追随者的恢复,ZooKeeper 能够在他们开始处理请求后再次提高吞吐量。

参考翻译自官网:zookeeper.apache.org/doc/current…

我是纪先生,用输出倒逼输入而持续学习,持续分享技术系列文章,以及全网值得收藏好文,欢迎关注公众号,做一个持续成长的技术人。