P99大会:Rust、Linux、SLO和性能优化

随着今年免费虚拟会议的筹备工作进入高潮,现在是分享过去一些最受关注的会议的好时机。

译自 Rust, Linux, SLOs and All Things Performance at P99 CONF,作者 Cynthia Dunlop。

P99 CONF 是一场免费的虚拟会议,专注于性能。每年,来自世界各地的数千名对延迟痴迷的工程师都会参加 P99 CONF。它纯粹是技术性的,有意地虚拟化,高度互动且以开源为中心。

ScyllaDB 于 2021 年启动了 P99 CONF,旨在连接和培养那些痴迷于低延迟工程的技术人员社区,并且它确实引起了关注,这得益于许多知识渊博的演讲者分享了他们的优化策略、经验教训以及对性能未来趋势的见解。

随着我们为 P99 CONF 24 做准备(稍后会详细介绍),我们认为现在是分享过去 P99 CONF 中一些最受关注的会议的好时机。您还可以通过 点播库 狂看 150 多场技术讲座(免费,无门槛)。

Rust 和低延迟系统的未来 - Bryan Cantrill

任何回顾都无法体现 Bryan Cantrill(Oxide Computer Company 的联合创始人兼首席技术官)信息量大且充满激情的主题演讲。

在短短 20 分钟内,他带领观众回顾了迄今为止的计算历史,对我们今天所处的位置进行了尖锐的批评,并让观众看到了该行业未来的发展方向。我们在“Bryan Cantrill 关于 Rust 和低延迟系统的未来”中以文章的形式写下了它,但相信我们 - 您需要观看这段视频。

以下是一段预告:Cantrill 用他自己的话说出了他的结论:

“Rust 实际上是自 C 语言以来第一种真正存在于硬件和软件边界上的语言。这就是它指引我们走向未来的原因。

“赖特定律意味着我们将拥有更多地方的计算能力。我们已经看到了这一点。这些计算元素将是专用型的。不要指望您的通用 CPU 会被塞进 SmartNIC 中。它会消耗太多功率。我们无法在下面拥有那么快的内存。

“但我们可以把 Rust 放到那里。Rust 可以适应这些地方。我们将看到更多令人兴奋的全新面向硬件的 Rust 系统,这些系统 - 由于 no_std - 将能够相互构建。

“这是一个开发高性能低延迟系统的激动人心的时刻,Rust 革命已经到来。”

哎呀!我用 Rust 重写了它 - Brian Martin

Twitter(现为 X)服务的可扩展性和效率在很大程度上依赖于高质量的缓存产品。该团队在那里开发了 Pelikan 作为缓存系统,因为 Memcached 和 Redis 无法完全满足他们的需求。他们对 Pelikan 的首要任务是“通过面向延迟的设计和精简实现,实现一流的效率和可预测性”。最初,这是通过 C 实现来实现的。但是,随后的两个项目将 Rust 引入了框架,并取得了相当令人印象深刻的开发速度。

当他们决定为 Pelikan 添加 TLS 支持时,Twitter 软件工程师 Brian Martin 怀疑用 Rust 完成这项工作比用 C 完成更快、更高效。但为了获得批准,Rust 实现必须与 C 实现的性能相匹配(或超过)。

使用现有的基于 Rust 的 Twemcache 的初始原型从性能角度来看并不乐观;它们产生了 25% 到 50% 的 P999 延迟增加,以及 10% 到 15% 的吞吐量下降。即使 Martin 加倍努力优化 Rust 原型的性能,他也看到了微不足道的效果。在经历了更多令人沮丧的性能测试结果后,他考虑了几种不同的实现方法。幸运的是,就在他权衡潜在的折衷方案时,他发现了一种新的存储设计,使将整个存储库移植到 Rust 变得更加容易。

Martin 在那时全力投入 Rust,使用简化的单线程应用程序,所有内存分配都在 Rust 中管理。结果如何?100% 的 Rust 实现不仅提供了与 C 实现和 memcached 相当或超过的性能:它还改进了整体设计,并通过“出色的语言特性和工具”使编码变得更加自信,Martin 随后深入研究了这些特性和工具。

保持低延迟和高吞吐量 - Avi Kivity

吞吐量和延迟始终处于紧张状态。ScyllaDB 首席技术官兼联合创始人 Avi Kivity 在他的主题演讲中重点讨论了如何通过使用应用程序级优先级调度在单个应用程序中同时实现高吞吐量和低延迟。

Kivity 从概述吞吐量计算 (OLAP) 和延迟计算 (OLTP) 之间的鲜明对比开始,并解释了在单个应用程序中混合这两种类型的作业有意义的场景。当需要混合时,两个核心操作至关重要:

  1. 将延迟作业和吞吐量作业的不同任务隔离,以便您可以测量和控制它们。
  2. 以允许延迟作业快速完成的方式对其进行调度,而不会受到吞吐量作业的干扰。

但魔鬼在于细节。您是否采用将任务隔离在线程中并让内核对其进行调度的常用方法?这通常更容易,但它无法提供足够的控制或效率来实现最佳结果。

另一种选择是应用程序级任务隔离。在这里,每个操作都是一个普通的对象,任务在少量线程上进行多路复用(理想情况下,每个逻辑核心一个线程,吞吐量敏感任务和延迟敏感任务都在同一个线程上)。并发框架将任务分配给线程并控制任务执行的顺序。这意味着您可以根据自己的意愿微调一切,但所有这些微调都可能上瘾,分散您对其他关键任务的注意力。更多优势:低开销、更简单的锁定、良好的 CPU 亲和性和更少的内核意外。这是一个不太成熟(但正在改进)的生态系统,但 Kivity 坚信,额外的努力会带来巨大的回报。

在可视化执行时间线的外观后,Kivity 详细介绍了切换队列、抢占技术和使用停滞检测器。最后,他解释了这一切如何在现实世界的例子中发挥作用:ScyllaDB 数据库。

痛苦指标和后果 - Gil Tene

Gil Tene 的传奇“oh sh*t” 演讲促使许多工程师重新思考他们对测量 P99 和类似延迟的方法。但在沉迷于如何改进性能测量超过十年并看到分布式系统如何发展之后,Gil 自己对该主题的方法也发生了变化。

从“奇爱博士”到“黑客帝国”再到祭祀山羊,Azul Systems 的联合创始人兼首席技术官 Tene 带领观众踏上了一段旅程,从高延迟峰值到测量绝望的低谷。他解构了我们用“所有漂亮的图表”真正看到了什么,更重要的是,我们错过了什么。这次演讲会让你想知道在我们活动徽标中看到的图表背后真正发生了什么——并且可能让你对 P99 的概念本身思考很多。在看似绝望的低谷中,Tene 展示了一个相当可怕的例子,说明了如何改善图表上的性能的操作会严重损害最终用户体验。真是痛苦。

但 Tene 仍然相信,实际上有可能克服我们接受的性能测量方法的缺点,只是不像他最初认为的那样。痛苦中存在希望。隧道尽头的光明。甚至彩虹(也许是因为 Tene 是从夏威夷加入我们的)。事实证明,工程师可以通过学会热爱痛苦来防止痛苦。如果你还不明白,现在是时候服用红色药丸并观看他的演讲了。

奖励:在“如果 P99 延迟是 BS,那么替代方案是什么?” 中了解更多信息

从 SLO 到“年度游戏” - Charity Majors

Charity Majors 以其尖锐的见解而闻名——她在 P99 CONF 主题演讲中谈论服务级别目标 (SLO) 也不例外。延迟敏感的工程师可以从游戏中学到很多东西——在游戏中,任何不完美体验都会破坏即使是最具想象力的设计。这就是工具和遥测发挥作用的地方。正如 Majors 所说,“不可能没有问题。但有可能在用户注意到之前找到并解决问题。你真的希望用户认为这是理所当然的。”

但你如何衡量这种体验?继 Tene 首次介绍的丑陋的 P99 现实之后,Alex HidalgoBrian Taylor 也对此进行了探讨,Majors 宣称,“聚合是胡说八道。每个人的体验都很重要。任何一个可以登录的玩家都可以在论坛上掀起一场风暴。” 你的系统可能拥有四个九,但仍然……

  • 今天登录的每个人都可能将他们的状态保存到一个无响应的分片上,并且认为你完全宕机了。
  • 登录的延迟可能在某些地区对每个人都超时。
  • 注册时,对支付的更新可能失败。
  • 有效的可观测性是工程体验和用户体验之间隐藏的纽带。

根据 Majors 的说法,“没有可观测性,你实际上是在蒙着眼睛开车。你没有戴眼镜就沿着高速公路飞驰。” 可观测性应该帮助你看到引擎盖下发生了什么——让你能够调试代码,重建任何用户的体验,甚至在不发布新代码的情况下理解新的场景。它应该帮助你超越“这坏了?”,而是“这是如何工作的,我的用户正在经历什么?” 你在这方面做得越好,你遇到的故障就越少。

但是,如何才能在游戏或其他复杂的、高度分布式的系统中实现这种独角兽般的可观测性水平呢?这些系统:

  • 部署在多个云、数据中心和区域
  • 由世界各地的众多团队设计和开发
  • 在数千种设备类型上使用
  • 容易出现巨大的并发问题和“雷鸣般的羊群”

这就是 Majors 多年来一直在解决的问题,这也导致了她最新的冒险——成为 Honeycomb.io 的“意外创业公司创始人”。观看她的主题演讲,了解前进的清晰路径,分享她辛苦得来的经验教训,这样你就可以提供一种完全是独角兽和彩虹的用户体验。

使用 eBPF 进行高性能网络 - Liz Rice

Liz RiceCisco Isovalent 的首席开源官,向与会者介绍了 Cilium(云原生计算基金会的一部分)如何通过使用 eBPF 绕过网络堆栈的部分,从而提高吞吐量,释放 CPU 使用率,并使 Kubernetes 网络更加高效。

使用 XDP(Express Data Path),Cilium 可以在网络接口卡上运行 eBPF 程序,使你能够在网络数据包到达时立即利用 eBPF。例如,正如 Rice 所示,你可以使用 eBPF 作为一种非常快速高效的方式来识别和丢弃“死亡数据包”。值得注意的是,这种缓解措施可以动态加载,无需安装内核补丁或重新启动机器。这仅仅是你可以使用 eBPF 动态更改系统中网络行为的一个例子。

eBPF 还可以用于操作数据包——例如,更改数据包中包含的源地址和目标地址以进行负载均衡。当数据包到达时,eBPF XDP 程序可以确定将其发送到哪里——在该主机上或发送到另一台机器——而无需由内核的网络堆栈处理数据包。这使得性能能够显著提高。(示例 A:阅读 Seznam.cz 如何通过 运行基于 XDP 的负载均衡器与 IPVS 负载均衡器 实现两倍以上的吞吐量,并节省了“难以置信的 CPU 使用率”。)

除了 XDP 之外,eBPF 程序还可以附加到网络堆栈中的各种不同点,这在处理 Kubernetes 的复杂网络堆栈时尤其有用。正如 Rice 的演示、火焰图和基准测试所示,这为吞吐量和 CPU 提升提供了更多机会。观看视频,亲眼见证性能影响。

极端 HTTP 性能调优 - Marc Richards

Marc Richards 拥有十多年的高级性能调优经验,最近为用 C 编写的 API 服务器处理了一个低级系统性能调优项目。在回顾这段冒险经历时,他的演讲从三个建议开始,这些建议适用于任何对开始低级性能调优感兴趣的人:

  • 你不需要成为内核开发人员或巫师系统管理员;它需要好奇心和毅力,但你绝对可以边学边做。
  • FlameGraph 和 bpftrace 彻底改变了游戏规则,使这项工作变得更加容易。
  • 未来将出现许多新的基于 eBPF 的工具,这些工具将使事情变得更加容易。

转向调优的具体细节,Richards 概述了他针对该系统的九个优化类别,该系统从一开始就具有相当高的性能(P999 为 1.32 毫秒,每秒 224k 个请求)。

在“应用程序优化”类别中,他取得了惊人的 55% 的提升(达到每秒 347k 个请求)。通过修复一个简单的编码错误,他能够让应用程序在所有可用的核心上运行,从而提高了 25%。使用 GCC 标记的正确组合来编译框架和应用程序,带来了 15% 的提升。将框架更新为使用 SEND/RECV 调用而不是更通用的 WRITE 和 READ,又增加了 5%。最后,他通过移除 pthread 开销,获得了额外的 3% 的提升。

Richards 继续解释了他应用的各种其他优化,详细说明了为什么他决定进行每个更改以及它带来的性能改进。该视频涵盖了从完美局部性和中断优化到“爱管闲事邻居案例”的各种优化。为了比 Richards 在他 20 分钟的演讲中提供的更深入的探讨,请参阅他的博客“极端 HTTP 性能调优:在 4 个 vCPU EC2 实例上实现 1.2M API req/s”。

加入 P99 CONF 2024 社区

就像 P99 CONF 社区一样,我们痴迷于持续优化。这将我们带到了 P99 CONF 2024。以下是议程的预览:

  • Gunnar Morling: “1BRC – 针对 Java 社区的极客陷阱”
  • Andy Pavlo: “数据库和操作系统之间爱恨交织关系的下一章”
  • Amos Wenger (fasterthanlime): “Rust + io_uring + ktls:我们能使 HTTP 多快?”
  • Michael Stonebraker: “你做错了”
  • Jose Fernandez: “Netflix 使用 eBPF 进行噪声邻居检测”
  • Carl Lerche: “Rust:用于编写数据库应用程序的生产力语言”
  • Tanel Poder: “使用 eBPF 离 CPU 采样来查看数据库的真实等待情况”
  • Bryan Cantrill: 待定
  • Avi Kivity: “为 ScyllaDB 设计查询队列”
  • Liz Rice: “使用 eBPF 和 Netkit 实现零开销容器网络”

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注