共计 3894 个字符,预计需要花费 10 分钟才能阅读完成。
分布式系统通常都依赖一个仲裁系统协同工作,一般这样的系统通过仲裁来保证信息的准确传达,以避免出现脑裂。这类系统通过牺牲通用性换来了充分的设计余地,这种做法显然已经被不断扩散的各种具体实现所例证。这样的系统有很多,例如:chubby,ZooKeeper,etcd 和 consul 等。尽管这些系统的理念和协议不同,但是提供的都是类似的基于 key-value 的分布式仲裁。作为将 etcd 打造成分布式系统最受瞩目的基础组件计划的一部分,etcd 团队开发了一款全新的代理,zetcd,无需变动就可以让 etcd 集群消费 ZooKeeper 的服务请求。
ZooKeeper 是第一个开源实现的仲裁软件,这促使它成为众多分布式系统偏好的后端。理论上来说这些系统应该可以跟 etcd 兼容,但由于历史原因,事实并非如此;etcd 集群无法替代 ZooKeeper,其数据模型和客户端协议跟 ZooKeeper 应用不兼容;反之亦然。倘若该系统已经投产,那么几乎没什么动力可以推动它接入新的后端,引入新的复杂度。
幸运的是,etcd v3 API 正准备通过一个标准代理 zetcd 实现对 ZooKeeper 数据模型的模拟支持,zetcd 是一个由 etcd 团队开发的全新开源项目,今天发布了 zetcd 第一个 beta 版本,v0.0.1,目标是在生产系统中管理和部署 zetcd 系统。
zetcd 代理部署在 etcd 集群前面,服务于一个模拟的 ZooKeeper 客户端端口,使得 ZooKeeper 应用可以在上层原生调用 etcd。总体上来说,zetcd 接受 ZooKeeper 的客户请求,转化成 etcd 的数据模型和 API,将请求转发到 etcd,然后将返回信息以客户端可以理解的方式转发回去。zetcd 的性能跟 ZooKeeper 不相上下,并且简化了 ZooKeeper 集群与 etcd 之间的管理和操作复杂性。本文将揭示如何使用 zetcd,zetcd 工作原理以及性能基准。
zetcd 运行所需的是一个 go 编译器,从互联网上获取的源代码,以及一个可以运行 etcd 的系统。以下例子展示了从获取 zetcd 源码,一直到如何在 zetcd 上运行 ZooKeeper 命令。由于均是基于开发分支构建的 etcd 和 zetcd,所以并不建议在生产环境这样做,这只是一个讲解如何使用的简单示例。
首先,获得 etcd 和 zetcd 源码,并编译成二进制代码:
go get github.com/coreos/etcd/cmd/etcd
go get github.com/coreos/zetcd/cmd/zetcd
其次,运行 etcd,将 zetcd 连接到 etcd 客户服务端:
#etcd uses localhost:2379 by default
etcd &
zetcd -zkaddr localhost:2181 -endpoints localhost:2379 &
通过增加订阅和创建一个 key 来试用 zetd:
go install github.com/coreos/zetcd/cmd/zkctl
zkctl watch / &
zkctl create /abc "foo"
从概念上讲,上述例子即完成在一个单个的 etcd 实例上增加一层 zetcd。
深入来讲,zetcd 会将 ZooKeeper 的数据模型翻译成适配 etcd API。对于 key 查找,zetcd 将 ZooKeeper 层级式目录转换成 etcd 扁平的二分键值空间(flat binary keyspace)。为了管理元数据,当写入 etcd 后端时,zetcd 利用内存级别的事务将信息安全、原子地更新为 ZooKeeper znode 信息。
ZooKeeper 以目录方式列出 key(getChildren),而 etcd 则是通过间隔(Range)方式。下图讲解了 zetcd 如何对 etcd 下的 key 进行编码从而有效地支持以目录形式列出。所有在 etcd 中的 zetcd key 都有一个包括全目录名的前缀(例如:”/”和“/abc”分别代表深度为 0 和 1)。要列出一个目录时,zetcd 发出一个带前缀的 range 请求(例如 [“/zk/key/002/abc/”,“/zk/key/002/abc0”)来列出满足目录深度和路径的所有 /abc/ 下的 key。深度限制只针对目录本身;如果 zetcd 只使用路径而不使用深度,那么 etcd 将返回这个目录下的所有 key,zetcd 则会丢弃该结果,反之则只返回本目录下的 key。
每个 ZooKeeper key 在 ZNode 里都带有一些元数据,即 key 的调整,版本和权限等。尽管 etcd 也有每个 key 的元数据,却比 ZNode 要简单很多,例如因为没有目录也就没有子版本,因为 etcd 使用的是基于角色认证的机制因此也就没有 ACL,因为实际的时钟超出范畴所以没有时间戳。这些额外的元数据会被映射为对应的 key,用来描述一个完整的 ZNode。修改元数据时,zetcd 利用内存级别的软事务来自动更新 key 的子集,确保 ZNodes 不需要昂贵的加锁机制就可以保持一致。
此外,zetcd 可以和一台授权的 ZooKeeper 服务器做动态校验。为了做比较,zetcd 可以同时连到 etcd 和外部 ZooKeeper 服务器。当客户端发起请求给该模式下的 zetcd 时,请求会被同时转发到 zetcd 和 ZooKeeper 服务端。如果两个服务器响应的数据不一致,zetcd 会给此响应标识一个警告。
由于数据的转换以及额外的网络开销,也许很容易觉得这样的模拟不切实际。尽管对于 ZooKeeper 或者 etcd 集群来说,zetcd 有额外的花销,但是它仍然有一个优势,即某些 etcd 应用安装完毕后仍然需要 ZooKeeper 来协调的场景。例如,早期用户报告称在 zetcd 里通过 etcd 的 TLS 加密流量比一个类似的经典 ZooKeeper 配置更简单。在这些场景中,支持同一种 ZooKeeper 协议所带来的简单可靠性比性能更重要一些。跟 etcd 性能工具的接口及报告形式类似,zetcd 命令行工具 zkboom 可以用来判断一个 zetcd 的性能基准是否满足要求。其它 ZooKeeper 性能工具应该也可以用在 zetcd;zkboom 为用户提供了便利,我们不妨试试用它来做下创建 key 的测试:
go get github.com/coreos/zetcd/cmd/zkboom
zkboom --conns=50 --total=10000 --endpoints=localhost:2181 create
zetcd 应当可以为小负载提供充分的性能保障。一个简单两节点配置的延迟基准表明 zetcd 是可以承受大量请求的。具体配置为两台 Linux 服务器通过一个千兆交换机互联,其中一台设备在 RAID 磁盘配置上运行代理和和服务端,另外一台设备用于产生客户请求。zkbook 通过创建一个空的 key 存储,然后从中读取 128Kbytes 的键值对来进行测量。用户请求被限制在每秒 2500 个请求,然后逐渐增加并发客户端数量。ZooKeeper 3.4.10 和 etcd 结果对比见下图。
下图揭示了 zetcd 客户端并发数与创建 key 的平均延迟之间的关系。由于 etcd 在延迟上比 ZooKeeper 要有 5 -35ms 的优势,zetcd 有足够余地处理由于额外负载和网络跳转造成的延迟。比起 ZooKeeper,zetcd 代理始终还是存在 20ms 左右的差距,但是从处理 2500 请求的吞吐量数据来看,并没有出现队列堵塞。一种对 zetcd 写比较慢的解释是,与读不一样,由于数据模型上存在差异,所以在每个 ZooKeeper key 写时需要写多个 key。
下图揭示了 zetcd 客户端并发数与 key 取值的平均延迟之间的关系。由于 ZooKeeper 的取值延迟比 etcd 要快那么 2ms 左右,想要 zetcd 提供数据的速度快过 ZooKeeper 的话恐怕还得依赖于 etcd 本身性能的进一步提升。然而,尽管 zetcd 需要从 etcd 请求额外的 key 来模拟 Zookeeper znode 的元数据,zetcd 的命中延迟在等待 etcd key 提取数据方面只增加了大概 1.5ms。zetcd 在 key 的数据提取操作方面仅需一次往返,因为读请求会被打包到一个 etcd 事务中。
zetcd 承诺上述性能基准测试的结果是合理的,在可接受的延迟情况下,可以轻松支撑每秒上千个操作。以上模拟对于 Mesos,Kafka 和 Drill 替代 ZooKeeper 提供了一个替代选择。但是对于 zetcd 本身来说性能方面仍有不少的提升空间。与此同时测试更多的 ZooKeeper 应用也会进一步推动 zetcd 成为 ZooKeeper 服务器的替代品。
zetcd 从去年十月开始在开源社区发行,最近刚发布第一个版本:zetcd v0.0.1。尽管是第一个 beta 发行版,但是已经为未来生产系统提供稳定管理和部署。如果跟 etcd 配合起来使用,运行 zetcd 的系统将会一套自驱动的“ZooKeeper”集群,它可以自动后台升级,备份和 TLS 管理。
etcd 为分布式系统提供可靠、高效的配置管理服务,在 Docker、Kubernetes、Mesos 等平台中扮演了越来越重要的角色。作为 2013 年开始的项目,它还很年轻,官方文档中缺乏实现上全面、系统的介绍,本课程深入浅出地介绍了 etcd 的实现,并为运维和二次开发提供了系统的指导和建议。
![post-qrcode](https://www.xgss.net/wp-content/uploads/2023/07/二维码-微信公众号256x256.jpg)