作者: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 框架以一种非常特定的方式度量服务网格的行为:
- 它在控制平面和数据平面的最高点测量内存使用率。换句话说,在运行的任何时间点,来自控制平面的最高内存使用量(作为一个整体,即将所有子组件聚合在一起)被报告为该运行的控制平面内存使用量。
- 类似地,任何单个数据平面代理的最高内存使用量都被报告为运行时的数据平面使用量。
- 它以类似的方式测量 CPU 使用率,使用 CPU 时间作为指标。
- 它从客户端(负载生成器)的角度测量延迟,包括集群网络上的时间、应用程序中的时间、代理中的时间等等。延迟被报告为分布的百分比,例如 p50(中位数)、p99、p999(99.9%),等等。
(关于这方面的更多信息,请参阅下面的总结和讨论。)
还要注意,这个基准测试报告的数字,是服务网格和设备及其环境的函数。换句话说,这些不是绝对的分数,而是相对的分数,只能在相同的环境和相同的方法下,与其他选择进行比较。
测试了哪些服务网格特性?
虽然,每个服务网都提供了大量的功能,但在这些实验中,只有其中的一个子集真正发挥了作用:
- 两个服务网都启用了 mTLS,并在所有应用程序之间,加密流量和验证身份。
- 两个服务网格都是跟踪指标,包括 L7 指标,尽管这些指标在本实验中没有使用。
- 两个服务网格都在默认情况下 INFO 级别记录了各种消息。我们没有配置日志记录。
- 这两个服务网格都能够添加重试和超时,以及以各种方式转移流量,但是在这个实验中没有明确使用这些特性。
- 没有启用分布式追踪、多集群通信或其他“网格”特性。
结果
我们的实验结果如下图所示。这些图表中的每个点都是这 5 次运行的平均值,误差条代表与该平均值的一个标准差。条形图本身代表 Linkerd(蓝色),Istio(橙色)和无服务网格的基线(黄色)。
20 RPS 下的延迟
从相对平静的 20 RPS 水平开始,我们已经看到了用户面对延迟的巨大差异:Linkerd 的中值延迟是 17ms,比基线的 6ms 高出 11ms。相比之下,Istio 的平均延迟为 26ms,几乎是 Linkerd 额外延迟的两倍。在最大的时候,Linkerd 在基线的 17ms 的延迟上增加了 53ms,而 Istio 的最大延迟增加了 188ms,超过了 Linkerd 额外延迟的三倍。
从百分位数来看,我们可以看到,Istio 的延迟分布从第 99 百分位数急剧上升到约 200ms,而 Linkerd 则从更高百分位数逐渐上升到 70ms。(请记住,这些延迟数是从客户端的角度来衡量的,也就是说,该应用程序的用户实际体验是什么。)
200 RPS 下的延时
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 毫秒。
2,000 RPS 下的延时
最后,在 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 基准框架。在未来的工作中,我们可能会考虑改变一些东西。例如:
- 衡量累积资源消耗,而不是最大资源消耗可能更能反映真实成本。
- 根据所消耗的核心而不是 CPU 时间来测量 CPU 可能是对内存测量方式的更好的模拟。
- 计算所有运行的所有数据的延迟百分位,而不是取单个运行的百分位平均值,在统计上更准确。
此外,我们的实验比 Kinvolk 2019 年的实验简单得多,该实验涉及 30 分钟的持续流量、不同的集群、不同的数据中心,以及其他控制可变硬件或网络的技术。在我们的案例中,我们明确地关注于首先找到一个低变化的环境来运行测试。
Linkerd 为什么更快更轻?
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 适合所有人
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