返回 登录
2

zetcd:脱离ZooKeeper运行ZooKeeper应用程序

原文zetcd: running ZooKeeper apps without ZooKeeper
作者:Anthony Romano
翻译:雁惊寒

译者注:zetcd是一款架在ZooKeeper与etcd之间的代理程序,它可以将ZooKeeper客户端的请求消息转换成etcd要求的格式,并转发给etcd,然后将响应消息转换后返回给客户端。本文介绍了zetcd的使用方法、工作原理以及性能评测。以下是译文。

分布式系统需要依赖分布式一致性来协调工作。通常情况下,提供分布式一致性担保信息的系统会接收到按顺序投递过来的消息,这样就不会产生脑裂冲突(split-brain conflicts,译者注:本来一个大脑的两个半球是互相配合的,但是现在分裂变成了两个独立的大脑,并且都认为对方已死。此时,双方都会去尝试接管集群资源,这样就可能会造成冲突,产生严重的后果)。这类系统的用途是显而易见的。像chubbyZooKeeperetcdconsul这些项目,尽管它们的原理和协议各不相同,但它们都侧重于为分布式一致性提供类似的基本键值原语。为了让etcd成为分布式系统中最具吸引力的项目,etcd团队开发了一款新的代理服务器程序:zetcd,使用这款软件,etcd集群无需修改即可处理ZooKeeper客户端的请求。

ZooKeeper是这方面第一个流行起来的开源软件,它是很多分布式系统的首选后端软件。这些系统理论上也可以搭配etcd一起运行,但是由于历史原因,实际上根本实现不了。etcd集群不支持ZooKeeper,因为etcd的数据模型和客户端协议与ZooKeeper应用程序不兼容。ZooKeeper应用程序也不是原生的支持etcd;如果系统已经在稳定运行了,那么没有必要去为了适应新的后端软件而让系统更加复杂。幸运的是,etcd的第三版API相当的牛逼,它可以通过一个普通的代理来模拟ZooKeeper客户端的数据模型,这就是zetcd,一个由etcd团队开发的新的开源项目。今天,zetcd发布了第一个测试版,v0.0.1版,这为在生产系统中管理和部署zetcd打下了基础。

zetcd代理位于etcd集群的前端,它提供了一个模拟ZooKeeper客户端的端口,让原版的ZooKeeper应用程序可以运行在etcd上。其基本原理是,zetcd将ZooKeeper客户端的请求转换为适合于etcd数据模型和API要求的消息,将发送给etcd,然后将etcd的响应消息转换后返回给客户端。该代理的性能可以与ZooKeeper相媲美,利用etcd的特性和工具可以简化ZooKeeper集群管理。下文将展示zetcd的使用方法和工作原理,并分享一些性能评测数据。

zetcd入门

让zetcd运行起来需要三样东西:一个go编译器、一个能够获取源代码的互联网连接,以及一个可以运行etcd的系统。下面的示例展示了如何用源代码编译生成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 &

试用zetcd,启动查看并创建一个key:

go install github.com/coreos/zetcd/cmd/zkctl
zkctl watch / &
zkctl create /abc "foo"

这个例子展示了在一个独立的etcd实例上部署了一个zetcd代理层:

zetcd拓扑图

一个简单的zetcd服务器拓扑

那么这个zetcd代理层是做什么的呢?

ZooKeeper接入etcd3

在底层,zetcd将ZooKeeper的数据模型转换为适合的etcd API的数据。对于key的查找,zetcd将ZooKeeper的分级目录转换为etcd的普通二进制keyspace。对于元数据的管理,zetcd利用事务内存安全地和原子地将ZooKeeper znode信息更新到etcd后端。

ZooKeeper是按目录列出所有的key(getChildren),而etcd是按区间(Range)列出所有的key。下图说明了zetcd是如何在etcd中对key进行编码以便可以快速地列出目录中的key。所有zetcd的key都有一个包括目录深度的前缀(例如,“/”和“/abc/”分别具有0和1的深度)。要列出一个目录,zetcd会给出前缀范围,这个前缀以目录的深度和路径来匹配相应的key(例如,前缀范围[“/zk/key/002/abc/”,“/zk/key/002/abc0”]用于列出/abc/)。这里的目录深度是为了限制目录本身被当作key。如果zetcd将路径当作是没有深度的前缀,那么目录下的所有key,而不是只有其直接子节点,会由etcd返回并被代理抛弃。

zookeeper key hierarchy organization in etcd

etcd内部的ZooKeeper的key层次结构

每个ZooKeeper的key都在ZNode中携带了包含其修改记录、版本、权限的元数据。虽然etcd也包含了每个key的元数据,但却比ZNode中的简单:没有子版本,因为没有目录;没有ACL,因为etcd使用基于角色的身份验证方式;没有时间戳,因为实时时钟在etcd的作用范围之外。这个额外的元数据映射到一组描述了完整的ZNode的key上(见上图)。如果要调整元数据,zetcd会利用软件事务内存原子地更新key的子集,这样就能保持ZNodes的一致性,而不需要昂贵的加锁解锁开销。

此外,zetcd可以对真实的ZooKeeper服务器动态验证它的行为。作为比较,zetcd同时连接到etcd和外部ZooKeeper服务器。当客户端在此模式下向zetcd发出请求时,请求会同时分发到zetcd和ZooKeeper服务器。如果两个服务器的响应在语义上不一致,那么zetcd会通过交叉检查警告对响应进行标记。

微量性能评测

因为数据转换和网络上的损耗,很有可能就把zetcd的仿真当作是不切实际的做法。尽管单纯的ZooKeeper或etcd集群都有一些额外的成本,但是当etcd已安装并且可以使用,而一些应用程序只支持ZooKeeper调度的时候,zetcd的优势就体现出来了。例如,早期的用户报告声称,在zetcd中使用etcd的TLS加密流量比加密一个类似的经典的ZooKeeper配置来得更简单。在这种情况下,相对于简单地拥有一个可靠的使用ZooKeeper协议的集群来说,性能反而显得不那么重要了。

使用zetcd的命令行工具zkboom进行评测可以用来判断zetcd的性能是否达标。它的评测界面和报告与etcd的评测工具类似。其他的ZooKeeper评测工具也可以用于zetcd;为方便起见,zetcd提供了zkboom这个工具。我们来试一下运行zkboom来测试key的创建:

go get github.com/coreos/zetcd/cmd/zkboom
zkboom --conns=50 --total=10000 --endpoints=localhost:2181 create

zetcd可以为小型的工作负载提供足够的性能。延迟评测表明,使用简单的双节点配置,zetcd的仿真可用于中等的请求速率。该配置包含两台通过千兆交换机连接的现代Linux机器,其中一台机器使用机械磁盘RAID运行代理服务器软件,另一台机器用于生成客户端请求。使用zkboom来测量在一开始为空的key存储空间中创建和读取128个字节的键值对的延迟,客户端请求速率限制为每秒2500个请求,并逐步增加并发客户端的数量。我们拿ZooKeeper 3.4.10版和etcd的开发分支作比较。

下图展示了随着并发客户端数量的增加,zetcd的平均key创建延迟的变化情况。在本次评测中,由于etcd在延迟上相对于ZooKeeper有5ms到35ms左右的优势,因此zetcd就有了一些可用于适应网络损耗和数据处理的余量。zetcd代理比ZooKeeper逊色了大概20ms左右,但从吞吐量来看,并没有产生积压,因为它仍然保持了每秒2500个请求的速率。zetcd写入速度慢的一种解释是,它从etcd读取key的同时,由于数据模型的差异,要为每个新的ZooKeeper的key同时往etcd写入多个key。

key creation latency

随着并发客户端数量的增加,平均key创建延迟的变化情况(越低越好)

下图显示了随着并发客户端数量的增加,平均key获取延迟的变化情况。ZooKeeper的获取延迟比etcd稍低,差距大约为2ms左右,所以zetcd需要进一步的优化才有可能比ZooKeeper更快。为了模拟ZooKeeper znode元数据,尽管需要从etcd获取额外的key,但是zetcd延迟命中只比etcd获取key增加了大约1.5ms左右。这是因为zetcd获取key的操作只需要一次往返,所有的读取请求都被加入到单个etcd事务中。

key fetch latency

随着并发客户端数量的增加,平均key获取延迟的变化情况(越低越好)

向v0.0.1及以上版本发展

到目前为止,zetcd的前途是光明的。它的性能是合格的,可以轻松支撑每秒超过一千次的操作,并且延迟也是在可接受的范围之内。它的仿真已经足够接近ZooKeeper,可以替代Mesos,Kafka和Drill。但是在性能调优方面仍有一定的提升空间。同时,使用更多的ZooKeeper应用程序进行测试能够加快zetcd对ZooKeeper服务器的替代。

zetcd自去年10月份开始出现在开源社区上,并刚刚推出了第一个版本:zetcd v0.0.1。作为发布的第一个beta版本,zetcd为将来在生产系统中进行管理和部署做好了准备。当与etcd Operator配合使用时,这些运行zetcd的系统将成为具有自动后端升级、备份和TLS管理功能的自驱动“ZooKeeper”集群。要了解更多信息、提问或提出改进意见,请访问ze​​tcd GitHub,网址:https://github.com/coreos/zetcd/

评论