缓存砍掉六分之五,性能反而翻倍——Cloudflare 第 13 代服务器背后的工程故事
这是一道看起来无解的题。 新一代 AMD 处理器提供了两倍的核心数,但每个核心能用到的 L3 缓存只剩原来的六分之一。对于高度依赖缓存局部性的网络服务来说,这几乎是一个不可接受的退步。 Cloudflare 在评估第 13 代服务器时,就遇到了这个困境。这篇文章记录了他们是怎么走出来的——答案不是换一块更保守的 CPU,而是重写了整个软件栈。 原文链接:https://blog.cloudflare.com/gen13-launch/ Cloudflare 为第 13 代服务器选择了 AMD EPYC 第五代 Turin 系列处理器,其中最终落地的型号是 Turin 9965。 光看核心数,这是一个毫无悬念的升级: 核心数翻倍,Zen 5 架构带来更高的 IPC(每时钟周期指令数),每核功耗还降了 32%,DDR5-6400 提供更高的内存带宽。在纸面上,这是一次全面的代际飞跃。 但有一个数字藏在参数表的角落:每核 L3 缓存,从 Gen 12 的 12MB 骤降到 2MB,缩小了六倍。 这不是一个可以忽略的细节。 Cloudflare 没有凭直觉判断缓存减少会不会成为问题,而是用性能计数器直接测量。他们借助 AMD uProf 工具,收集了 CPU 在实际负载下的详细指标。 数据说明了一切: 这里有一个关键的硬件常识:L3 缓存命中大约需要 50 个 CPU 周期,而 L3 未命中需要去访问 DRAM,代价是 350 个周期以上,相差整整一个数量级。 每核缓存减少六倍,意味着同样的工作负载会产生更多的 DRAM 访问,每次访问都要多付出 300 个周期的代价。这个惩罚在高并发下会被迅速放大。 带着测量数据,Cloudflare 在 Gen 13 上跑了完整的基准测试,当时使用的是原有的 FL1 请求处理层(基于 NGINX 和 LuaJIT 实现,已有超过 15 年历史)。 结果如下: 最高密度的 Turin 9965 确实带来了 62% 的吞吐提升,但代价是高负载下延迟上涨超过 50%。 这个代价无法接受。请求处理延迟直接影响用户体验,50% 的延迟劣化不是一个可以用"总吞吐更高"来平衡的指标。 Cloudflare 与 AMD 合作,系统性地测试了各种硬件调优方案: 硬件预取器和 DF Probe Filter 调整:效果微乎其微。 增加 FL1 Worker 数量:能提升吞吐,但会挤占同机上其他生产服务的资源,不可持续。 CPU 绑核与隔离:收益有限。 AMD PQOS(平台服务质量扩展):这是测试结果最接近有用的方案。PQOS 允许以细粒度方式分配 L3 缓存给特定工作负载。 Turin 处理器内部由一个 I/O 裸片和最多 12 个核心复合体(CCD)构成,每个 CCD 有 16 个核心共享一块 L3 缓存。测试结果显示: 15% 已经是硬件调优的天花板了。距离让 Gen 13 真正发挥价值,还差得很远。 硬件调优触顶之后,唯一的出路是从软件层面解决问题。 幸运的是,这件事 Cloudflare 已经在做了。 在 2025 年的生日周期间,Cloudflare 宣布了 FL2 项目——对核心请求处理层的完整 Rust 重写,基于自研的 Pingora 和 Oxy 框架,替换掉有 15 年历史的 NGINX + LuaJIT 代码。 FL2 的立项动机并不是为了解决缓存问题,而是出于三个独立的工程需求:更好的安全性(Rust 的内存安全)、更快的开发迭代速度(严格的模块化系统)、以及整体性能改善(更低的 CPU 和内存消耗)。 但 FL2 的架构特点——更清晰的内存访问模式、更少的动态内存分配——恰好指向了一个假设:它对大 L3 缓存的依赖可能远小于 FL1。 这个假设后来被生产数据证实了。 随着 FL2 逐步推向生产,Gen 13 服务器上的实际运行数据开始验证团队的判断: 几个数字值得单独拎出来看: FL2 几乎彻底消除了延迟劣化。FL1 在 Gen 13 上高负载时延迟会上涨超过 50%,FL2 不仅没有劣化,还比 Gen 12 更好。这意味着 Gen 13 可以被推到更高的 CPU 利用率,同时严格满足延迟 SLA。 吞吐从 +62% 变成了 +100%。FL1 因为缓存瓶颈,无法将核心数的增加线性转化为吞吐。FL2 消除了这个瓶颈,让性能真正随核心数线性扩展,192 个核心终于能被充分利用。 最终确定量产的 Gen 13 选用 AMD Turin 9965,综合性能对比 Gen 12 如下: 最高 2 倍吞吐,且延迟保持在 SLA 范围内——流量峰值吸收能力翻倍,用户体验不受影响。 每瓦性能提升 50%——同等功耗下能处理更多请求,数据中心扩张成本降低,单请求碳排放显著下降。 机架吞吐提升 60%——在机架功耗预算不变的前提下,更高密度的计算能力可以在全球任意 PoP 节点部署,无需单独规划电力扩容。 Cloudflare Gen 13 的故事,表面上是一次服务器换代,深层是一个关于硬件与软件协同设计的典型案例。 AMD Turin 是一款为高吞吐密度优化的处理器,它主动牺牲了每核缓存来换取更多核心。这个选择在硬件设计层面是合理的——但它只有在软件能适配的前提下,才能兑现承诺。 FL1(NGINX + LuaJIT)的代码和执行模式,高度依赖大量 L3 缓存来维持性能。这不是设计缺陷,而是过去十五年里特定硬件环境下自然演化的结果。 FL2 的 Rust 重写,带来的不只是内存安全和代码可维护性的提升,还有对内存访问模式的根本性改善——更少的动态分配,更可预测的数据局部性,更低的缓存压力。这些特性让 FL2 能够充分利用 Turin 的核心数优势,而不被缓存不足拖累。 最值得记住的教训是:硬件提供了可能性,软件决定了能不能用上它。选择新一代硬件之前,先搞清楚自己的软件对硬件资源的假设,才能真正做到物尽其用。Gen 13 的硬件底牌
代次 处理器 核心/线程 每核 L3 缓存 Gen 12 AMD Genoa-X 9684X 96C/192T 12MB(3D V-Cache) Gen 13 候选一 AMD Turin 9755 128C/256T 4MB Gen 13 候选二 AMD Turin 9845 160C/320T 2MB Gen 13 候选三 AMD Turin 9965 192C/384T 2MB 先量化,再下结论
第一轮测试:吞吐涨了,延迟炸了
指标 Gen 12 FL1 Gen 13 9755 FL1 Gen 13 9845 FL1 Gen 13 9965 FL1 核心数变化 基准 +33% +67% +100% 吞吐提升 基准 +10% +31% +62% 低负载延迟 基准 +10% +30% +30% 高负载延迟 基准 >20% >50% >50% 硬件层面能调出多少?
FL2:恰好已经在做的那次重写
FL2 + Gen 13 的实测结果
指标 Gen 13 9965 + FL1 Gen 13 9965 + FL2 每 CPU% 处理请求数 基准 高 50% 延迟 vs Gen 12 劣化 >50% 优于 Gen 12 70% 吞吐 vs Gen 12 +62% +100% Gen 13 的三项业务数字
这件事说明了什么