Apache ZooKeeper vs. etcd3

在实现分布式服务协调方案时,有许多出色的系统,如 Apache ZooKeeperetcdconsul Hazelcast。如果您还没有听说过分布式协调,请参阅我的这篇关于分布式协调的文章,文章介绍了什么是分布式协调以及为什么需要它。

尽管这些系统中有些不是直接的分布式协调系统,但它们都可以用作分布式协调方案。不过,在分布式协调中有两个极为出色的系统:Apache ZooKeeper etcd。ZooKeeper 起源于 Hadoop 生态系统,而 etcd 则是 Google Kubernetes 使用的分布式协调方案。

本文将这两种实现方案与它们的优缺点进行了比较,这对开发人员未来在他们的分布式计算实现中选择合适的分布式协调方案时非常有用。

Apache ZooKeeper

ZooKeeper 最初是 Hadoop 的一个子项目,并发展成为 Apache Software Foundation 的顶级项目。目前,大多数 Apache 项目都在使用它,包括 HadoopKafkaSolr 等等。由于其良好的跟踪记录和稳定性,ZooKeeper 已成为世界上顶级的分布式协调系统之一。

ZooKeeper 使用 ZAB(ZooKeeper Atomic Broadcast,ZooKeeper 原子广播)作为其共识协议。如前所述,ZooKeeper 的目的之一是提供分布式数据存储。为了实现高可用性,ZooKeeper 在一个集合中运行——也就是说,一组节点共同运行 ZooKeeper 工作以提供其分布式特性。这组节点被称为 ZooKeeper 集合体。

一个 ZooKeeper 集合体应该总是包含奇数个节点。运行时,这些节点首先相互通信并选举一个 leader,这就是为什么 ZooKeeper 需要在奇数个节点的集合中运行。之后,其他节点被称为 Followers,而选出的节点被称为 Leader。现在连接到 ZooKeeper 的客户端可以连接到任何一个节点。客户端读取请求可以由任何节点处理,但写入请求只能由 Leader 来负责。因此,向 ZooKeeper 集合体添加更多节点将提高读取速度,但不会提高写入速度。

在 CAP(一致性,可用性和分区容忍性)定理的三个特性中,ZooKeeper 提供了一致性和分区容忍性。您可以在这里阅读关于 ZooKeeper 可靠性保证的更多信息。

ZNodes

存储数据时,ZooKeeper 使用一个树形结构,其中每个节点被称为 ZNode。ZNode 是根据从根节点开始的路径命名的。每个ZNode 都有一个名字。访问给定的 ZNode 时,使用从根节点开始的绝对路径。

上面显示的是 ZooKeeper 的 ZNode 结构的一个例子。每个 ZNode 可以存储高达 1MB 的数据。用户可以:

  • 创建 ZNode。
  • 删除 ZNode。
  • 将数据存储在特定的 ZNode 中。
  • 读取特定的 ZNode 中的数据。

除此之外,ZooKeeper 还提供了另一个非常重要的功能:Watcher API。

Zookeeper Watches

用户可以在任何给定的 ZNode 上注册 watch。当该 ZNode 发生任何变化(即创建,删除,数据更改,添加/删除子 ZNode)时,Watch API 会通知收听方。这是 ZooKeeper 提供的一项非常重要的功能,可用于检测分布式命令传递以及许多关键需求的变化。

ZooKeeper watch 唯一的缺点是一个给定的 watch 只触发一次。一旦 watch 被触发一次后,要在同一个 ZNode 上接收未来的事件,用户必须在该 ZNode 上设置一个新的 watch。但是,像 Apache Curator 这样的扩展可以在内部处理这些复杂的问题,并为用户提供更方便的 API。

Apache Curator

Apache Curator 是 ZooKeeper 的扩展客户端库。它内部处理 ZooKeeper 几乎所有的边界情况和复杂问题,并为用户提供了一个方便的 API。你可以在这里阅读更多有关 Curator 的信息。Curator 已经实现了许多分布式的 ZooKeeper recipes,包括共享重入锁,路径缓存,树缓存等等。

优点

我们已经讨论了大部分优点,但这里有更多:

  • 非阻塞完整快照(保证最终一致性)。
  • 高效的内存管理。
  • 可靠(已经存在了很长时间)。
  • 简化的 API。
  • 自动 ZooKeeper 连接管理与重试。
  • 完整的,经过充分测试的 ZooKeeper recipes 实现。
  • 一个可以更容易地编写新的 ZooKeeper Recipes 的框架。
  • 通过 ZooKeeper watches 支持事件。
  • 在网络分区中,少数和多数分区都将进行 leader 选举。因此,少数分区将停止运行。你可以在这里阅读更多。

缺点

  • 由于 ZooKeeper 是用 Java 编写的,它继承了 Java 的一些缺点(即垃圾收集导致暂停)。
  • 创建快照时(将数据写入磁盘),ZooKeeper 读取/写入操作暂时中止。只有我们启用了快照才会发生这种情况。否则,ZooKeeper 将作为内存中的分布式存储运行。
  • 对于每个新的 watch 请求,ZooKeeper 都会打开一个新的 socket 连接。这使得 ZooKeeper 更加复杂,因为它必须实时管理大量打开的 socket 连接。

etcd3

我们将讨论最新版本的etcd(etcd v3),与之前的etcd v2相比,它有很大的变化。与 Apache ZooKeeper 相比,etcd 是用 Go 编写的。其主要目标是解决 ZooKeeper 的缺点。尽管它并不像 ZooKeeper 那样古老而著名,但它是一个有前途的项目。众所周知的 Google 的容器编排平台 Kubernetes 使用 etcd v2 作为分布式存储来获取其 master 组件的分布式锁。这是 etcd 功能强大的一个例子。

etcd 使用 RAFT 一致性算法保证一致性,使其比 ZooKeeper 的 ZKB 协议更易于实现。etcd 提供了一个分布式键值存储,而不是树结构。它还提供以下保证,与 ZooKeeper 提供的保证非常相似:

API

etcd3 提供了在分布式存储上执行的以下操作。这些操作大部分类似于 ZooKeeper 提供的操作,并没有因为底层数据结构的不同而有区别。

  • Put:将一个新的键值对存储。
  • Get:获取对应于某个键的值。
  • Range:检索对应于键范围值(即 key1 key10 会检索键 key1,key2,...,key10 对应的值)。
  • Transaction:读取,比较,修改和写入的组合。
  • Watch:在一个键或键范围上。与 ZooKeeper 类似,发生变化时会通知。

有关这些操作的更多信息请参见此处。此外,etcd 的大部分分布式 recipes 都实现在 Apache Curator 上。

优点

  • 创建快照时用增量快照避免了暂停,这在 ZooKeeper 中是个问题。
  • 由于使用堆外存储,所以没有垃圾回收导致的暂停。
  • Watches 被重新设计,将旧的事件模型替换为在关键时间间隔内持久监听和事件复用的模型。因此,不会为每个 watch 分配一个 socket 连接。它在相同的连接上复用事件。
  • 与 ZooKeeper 不同,etcd 可以使用当前的 watch 持续监听。一旦 watch 被触发,就不需要设置一个新的 watch。
  • etcd3 拥有一个滑动窗口来保留旧事件,以便断开连接不会导致所有事件丢失。

缺点

  • 请注意,如果客户端超时或者客户端与 etcd 成员之间出现网络中断,客户端的运行状态可能不确定。当有 leader 选举时,etcd 也可能会中断运行。在此事件中,etcd 不会发送终止响应给客户端的未决请求。
  • 网络分区时,如果 leader 在少数分区中,序列化的读取请求仍然可以处理。

结论

我们讨论了 Apache ZooKeeper 和 etcd3 的主要特性和优缺点。ZooKeeper 是用 Java 编写的,被 Apache Software Foundation 项目广泛采用,而 etcd3 则由 Google(Kubernetes)提供支持。尽管 Apache ZooKeeper 是稳定的,并且以出色的分布式协调系统而闻名,但 etcd3 作为后起之秀很有前途。

由于 etcd 是用 Go 编写的,所以良好的客户端库不适用于 Java。相比之下,由于 ZooKeeper 已经有一段时间了,它也有一些用其他语言编写的良好客户端库。但是,使用 ZooKeeper 还是 etcd 应该取决于您的需求和您的首选语言。

进一步阅读

  1. Apache ZooKeeper Wiki
  2. Zookeeper Internals
  3. Serializability and Distributed Software Transactional Memory With etcd3
  4. Introduction to etcd3 by CoreOS CTO Brandon Philips
  5. etcd3 API
  6. Apache Curator in 5 Minutes

本文的版权归 LynnShaw 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏python3

习题1:第一个程序

863
来自专栏网络

Nginx 系列实用教程#2:性能

协作翻译 原文:Nginx Tutorial #2: Performance 链接:https://www.netguru.co/codestories/ngi...

2346
来自专栏机器学习实践二三事

Ipynb文件的打开

RT,ipynb文件用gedit直接打开的话,太多附加信息,此时需要在浏览器端打开 升级ipython 太低版本的ipython是不行的,出现的错误可能是这样的...

2258
来自专栏魏豪的专栏

另一个Web应用服务器——Tomcat

Tomcat 由于其比较突出的优势,譬如 技术先进、性能稳定,而且免费,所以深受 Java 语言爱好者的喜爱,并且得到了部分软件开发商的认可,目前已经成为比较流...

3310
来自专栏马涛涛的专栏

使用leancloud给简历加数据库,实现留言功能

数据必须存在服务器上,这样任何设备访问服务器都可以得到数据,如果存在客户端的本地,那么其他客户端设备无法读取到.所以数据必须存储在服务器的数据库上

2015
来自专栏Linyb极客之路

分布式定时任务调度框架之elastic-job简介

6303
来自专栏用户2442861的专栏

2013年 腾讯笔试题:fork()

如果你对fork()的机制比较熟悉的话,这个题并不难,输出应该是6个“-”,但是,实际上这个程序会很tricky地输出8个“-”。

1151
来自专栏信安之路

web应用渗透测试流程

对于web应用的渗透测试,一般分为三个阶段:信息收集、漏洞发现以及漏洞利用。下面我们就分别谈谈每个阶段需要做的事情。

1370
来自专栏林德熙的博客

win10 uwp 无法附加到CoreCLR 查询临时变量:

本文说的是在vs调试无法附加到CoreCLR。拒绝访问。已经如何去解决,可能带有一定的主观性和局限性,说的东西可能不对或者不符合每个人的预期。如果觉得我有讲的不...

691
来自专栏枕边书

用Lua定制Redis命令

前言 Redis作为一个非常成功的数据库,提供了非常丰富的数据类型和命令,使用这些,我们可以轻易而高效地完成很多缓存操作,可是总有一些比较特殊的问题或需求需要解...

4827

扫码关注云+社区

领取腾讯云代金券