作者:William Morgan
(Photo by Marc Sendra Martorell on Unsplash.)
两年前,Kinvolk[1]的优秀人员,对 Linkerd 和 Istio 的性能,进行了测试,结果显示,除了一个方面(Linkerd 使用了更多的数据平面 CPU)之外,Linkerd 比 Istio 的速度快得多,而且体积小得多。最近,我们在两个项目的最新版本中,重复了这些实验。我们的结果显示,Linkerd 不仅保持了比 Istio 更快的速度,而且在此过程中,消耗的数据平面内存和 CPU,也少了一个数量级。这些结果,甚至在吞吐量水平超过 Kinvolk 评估的 3 倍时得到维持,你可以自己复制测试。
了解更多,继续读下去!
2019 年,Kinvolk 公布了比较 Linkerd 和 Istio 的公开基准数据。这项工作完成了两件事。首先,它生成了一个开源服务网格基准测试工具,这样任何人都可以复制结果。该工具之所以引人注目,是因为它模仿了“现实生产”场景:它通过一个简单的微服务应用程序,发送了持续的流量,同时使用了 gRPC 和 HTTP 调用,并在内存和 CPU 方面,衡量了使用服务网格的成本,基于消耗以及增加的延迟。至关重要的是,从客户端的角度衡量了延迟,产生了面向用户的数字,而不是内部代理计时。
Kinvolk 制作的第二件事,是 Linkerd 和 Istio 在 2019 年前后的实际基准结果。这些数字表明,Linkerd 的速度非常快,而且 Linkerd 的资源消耗也非常小,除了一个例外,Linkerd 的数据平面(即它的代理)在最高负载水平下比 Istio 消耗更多的 CPU。
两年后,在两个项目发布了许多版本后,我们决定重新审视这些实验。
在这些实验中,我们将 Kinvolk 基准套件应用于这两个项目的最新稳定版本:Linkerd 2.10.2(默认安装)和 Istio 1.10.0(“最小”配置)。我们使用 Lokomotive Kubernetes 发行版在 Kubernetes v1.19 集群上运行了基准测试的最新版本。该基准运行在Equinix Metal[2]为 CNCF 项目提供的裸金属硬件上。
我们的第一步,是在 Equinix Metal 中找到一个可以跨运行交付一致结果的测试环境。这是一个非常困难的任务:我们尝试的许多环境,在运行之间产生了巨大的可变延迟,包括没有服务网格的基本情况。(例如,在我们尝试的一个环境中,基准测试报告,对于没有服务网格的情况,在 200 RPS 下,最大延迟从 26ms 到 159ms 不等!)
我们最终在 Equinix Metal dfw2 数据中心中找到了一个集群,它产生了一致的行为,运行之间的差异很小。这个集群由 s3.xlarge.x86 配置(Intel Xeon 4214 具有 24 个物理核@2.2GHz 和 192GB RAM)的 6 个工作节点组成,运行基准测试应用程序,加上一个相同配置的负载发生器节点,加上一个 c2.medium.x86 配置的 K8s 主节点。
接下来,我们讨论了工具的参数。虽然最初的 Kinvolk 工作评估的性能是每秒 500 个请求(RPS)和每秒 600 个请求(RPS),但我们想尝试更广泛的范围:我们评估网格的是 20 RPS、200 RPS 和 2000 RPS。在每个 RPS 级别,我们分别在 Linkerd、Istio 和无服务网格的基本情况下,连续运行 6 次,每次 10 分钟。所有基准和网格资源都在两次运行之间重新安装。对于每个级别,我们放弃了具有最高最大延迟的单一运行,只剩下 5 次运行。(我们的原始数据可供查阅[3]。)
请注意 Kinvolk 框架以一种非常特定的方式度量服务网格的行为:
(关于这方面的更多信息,请参阅下面的总结和讨论。)
还要注意,这个基准测试报告的数字,是服务网格和设备及其环境的函数。换句话说,这些不是绝对的分数,而是相对的分数,只能在相同的环境和相同的方法下,与其他选择进行比较。
虽然,每个服务网都提供了大量的功能,但在这些实验中,只有其中的一个子集真正发挥了作用:
我们的实验结果如下图所示。这些图表中的每个点都是这 5 次运行的平均值,误差条代表与该平均值的一个标准差。条形图本身代表 Linkerd(蓝色),Istio(橙色)和无服务网格的基线(黄色)。
从相对平静的 20 RPS 水平开始,我们已经看到了用户面对延迟的巨大差异:Linkerd 的中值延迟是 17ms,比基线的 6ms 高出 11ms。相比之下,Istio 的平均延迟为 26ms,几乎是 Linkerd 额外延迟的两倍。在最大的时候,Linkerd 在基线的 17ms 的延迟上增加了 53ms,而 Istio 的最大延迟增加了 188ms,超过了 Linkerd 额外延迟的三倍。
从百分位数来看,我们可以看到,Istio 的延迟分布从第 99 百分位数急剧上升到约 200ms,而 Linkerd 则从更高百分位数逐渐上升到 70ms。(请记住,这些延迟数是从客户端的角度来衡量的,也就是说,该应用程序的用户实际体验是什么。)
200 RPS 的数据说明了一个非常相似的故事,平均延迟数也几乎是相同的:Linkerd 的平均延迟 17ms 比基线的平均延迟 6ms 多了 11ms,而 Istio 的平均延迟 25ms 是 19ms。在最大的情况下,Istio 的 221ms 的延迟比基线的 23ms 几乎高出 200ms,而 Linkerd 的 92ms 的最大延迟是~70ms,比 Istio 少 2.5 倍。我们看到 Istio 的延迟也出现了同样的跳跃,从第 99 个百分位上升到近 200 毫秒,而 Linkerd 则从第 99 个百分位上升到近 90 毫秒。
最后,在 2000RPS(超过 Kinvolk 评估的三倍)时,我们再次看到相同的模式:在中间值,Linkerd 引入了额外的 9ms 延迟,而 Istio 的延迟是额外的 15ms;在最大的情况下,Linkerd 在基线 25ms 的基础上增加了 47ms,Istio 增加了这的 5x,增加了 253ms。一般来说,Istio 报告的每一个百分位都比 Linkerd 增加了 40%到 400%的额外延迟。
现在让我们转向资源使用。每个服务网格的 CPU 和内存消耗如下图所示。这些数字在所有吞吐量级别上都是相当一致的,所以我们将重点关注 2000 RPS 的最高负载场景。
从控制平面开始,我们看到 Istio 的控制平面平均使用 837mb,大约是 Linkerd 控制平面 324mb 内存消耗的 2.5 倍。与 Istio 的 3.7s 相比,Linkerd 的 CPU 使用时间小了几个数量级——控制平面 CPU 时间为 71ms。
然而,比控制平面更重要的是数据平面。毕竟,这是网格必须随着应用程序向外扩展的部分。这里我们可以看到另一个显著的差异:Linkerd 代理消耗的最大内存平均为 17.8mb,而 Istio 的 Envoy 代理消耗的最大内存为 154.6mb,是 8 倍的差距。类似地,Linkerd 记录的最大代理 CPU 时间是 10ms,而 Istio 是 88ms——几乎是一个数量级的差异。
在这些旨在模拟现实场景的基准测试中,我们看到 Linkerd 的性能显著优于 Istio,同时在关键数据平面级别上维持的资源成本要小许多个数量级。在最高吞吐量评估时,我们看到 Linkerd 在数据平面上消耗了 1/9 的内存和 1/8 的 CPU,同时提供了 75%的额外中值延迟和不到 Istio 的 1/5 的额外最大延迟。
基准测试既是一门艺术,也是一门科学。在这些实验中,我们有意识地选择坚持使用发布的 Kinvolk 基准框架。在未来的工作中,我们可能会考虑改变一些东西。例如:
此外,我们的实验比 Kinvolk 2019 年的实验简单得多,该实验涉及 30 分钟的持续流量、不同的集群、不同的数据中心,以及其他控制可变硬件或网络的技术。在我们的案例中,我们明确地关注于首先找到一个低变化的环境来运行测试。
Linkerd 和 Istio 在性能和资源成本上的巨大差异,主要归结于一件事:Linkerd 基于 Rust 的“微代理”,Linkerd2-proxy。这个微型代理为 Linkerd 的整个数据平面提供了强大的功能,而基准测试在很大程度上反映了它的性能和资源消耗。
我们已经写了很多关于 Linkerd2-proxy,以及我们在 2018 年黑暗时代采用 Rust 背后的动机。有趣的是,构建 Linkerd2-proxy 的主要原因,不是性能而是操作原因:运营一个像 Istio 这样基于 Envoy 的服务网通,常需要你成为一个操作 Envoy 的专家,我们不喜欢把这个挑战强加在 Linkerd 用户身上
令人高兴的是,选择构建 Linkerd2-proxy 也带来了显著的性能和效率提高。通过只解决“服务网格边车代理”这个非常具体的问题,我们可以在数据平面级别上非常高效。通过在 Rust 中构建 Linkerd2-proxy,我们可以驾驭这个生态系统中令人难以置信的技术投资浪潮:像 Tokio、Hyper 和 Tower 这样的库是一些世界上最好的系统思考和设计的焦点。
Linkerd2-proxy 不仅仅是令人难以置信的快速、轻和安全,它代表了整个 CNCF 领域中最尖端的技术。
奇怪的是,尽管 Linkerd 在这些基准测试中表现出色,但我们还没有集中精力对代理进行性能调优。我们期望在性能上花费时间将在这方面带来额外的收益。
我们也热切地关注着SMP 项目[4],作为基准标准的潜在来源。理想情况下,这些基准将由中立的第三方运行。这让我们想到:
如果你想自己复制这些测试,可以遵循基准测试说明[5]。
如果你尝试这样做,请查看我们上面关于测试方法的评论。找到能够交付一致结果的环境非常关键,特别是对于对网络流量、资源争用等非常敏感的最大延迟等问题。另外,请记住,你所得到的数字将是相对的,而不是绝对的。
让我们知道你的发现!
特别感谢 Equinix 的朋友们提供了 Kubernetes 环境,使这一切成为可能;CNCF,是他们让 Linkerd 项目得以进行这些实验,以及 Kinvolk,特别是 Thilo Fromm,带来优秀的基准测试。
Linkerd 是一个社区项目,由 CNCF 托管。Linkerd 致力于开放治理。如果你有特性请求、问题,或评论,我们希望你加入我们快速增长的社区!Linkerd 代码是在 GitHub 上托管,我们在 Slack、Twitter 和邮件列表上有一个繁荣的社区。快来加入我们一起玩吧!
[1]
Kinvolk: https://kinvolk.io/
[2]
Equinix Metal: https://www.equinix.com/
[3]
原始数据可供查阅: https://docs.google.com/spreadsheets/d/1x0QXFAvL0nWOIGL5coaaW1xwsju5EmSjsqjw6bwHMlQ/
[4]
SMP 项目: https://smp-spec.io/
[5]
基准测试说明: https://github.com/linkerd/linkerd2/wiki/Linkerd-Benchmark-Setup