用开源内核调度器重构 Meta 广告服务
- 在 Meta 的规模下,几毫秒的延迟退化都可能对广告效果产生显著的负面影响。
- 当一次 Linux 内核升级可能导致整个 Meta 广告投放机群的延迟回退时,我们转向 sched_ext —— 上游基于 BPF 的可扩展调度框架 —— 来构建一套针对广告投放负载量身定制的调度策略。
- 最终成果:广告检索阶段的尾部(第 99 百分位)延迟降低了 28%,节省了 3.28 兆瓦(MW)的功耗,参与排序的广告数量增加了 1.1%,充分证明面向特定负载的调度优化可以直接带来业务价值。
Meta 的广告投放机群在投放平台入口处平均每秒处理超过 500 万次请求,覆盖所有变现场景日均超过 4000 亿次1。每从 p99 延迟中省下一毫秒,平台上的用户看到的广告就更加相关,匹配质量提升也意味着广告主能获得更高的 ROI。

这为通过面向负载的调度来降低延迟提供了绝佳机会。这也是 Meta 的广告团队和 Linux 内核团队一直紧密合作,基于上游 sched_ext(基于 BPF 的可扩展调度框架)构建广告投放定制调度策略的原因。在此之前,我们一直沿用 Linux 内核中默认的通用调度器(CFS 和 EEVDF),它们在 CPU 间均衡线程时对具体负载一无所知。而在这里,我们清楚每个线程的用途和重要性。借助 sched_ext,我们可以把这部分认知直接编码进调度器:能改善 p99 请求延迟的工作优先调度,其余任务则退居其后。
sched_ext 在 Meta
sched_ext 是一个开源的、基于 BPF 的调度器框架,于 Linux 内核 v6.12 正式合入。我们在开发过程中与 Google 的 ghOSt 作者合作,共同设计了一个适合上游 Linux 集成的调度器。它已部署在 Meta 的多个服务中,显著降低了调度延迟。
在将我们的服务器集群升级到最新稳定版 Linux(内核 v6.9)时,我们发现 Linux 内核 v6.6 引入的新调度器 EEVDF(最早合格虚拟截止时间优先) 引发了延迟回归问题,导致广告排序的返回数量下降。结果是,一部分广告服务器不得不继续停留在旧版 v6.4 内核上,由此积累了大量技术债,也造成了运维层面的割裂。
鉴于 sched_ext 本身已经展现出强劲的性能,它成为解决这些调度回归问题的理想选择。
使用 sched_ext 实现定制化调度
sched_ext 允许调度器开发者以 BPF 程序的形式实现自定义调度策略。当某台主机开始运行广告业务负载时,就会应用一套针对广告优化的策略。此后,内核通过一组由事件驱动的回调来调用这个 BPF 调度器,以处理常见的调度事件,例如:
- 线程唤醒:当线程变为可运行时,选择一个 CPU。
- 入队:将线程放入运行队列。
- 派发:当 CPU 变为空闲时,选择下一个要运行的线程。
- 空闲状态转换:响应 CPU 进入或退出空闲状态。
从宏观上看,这个策略会把 CPU 软划分为两个池:一个分配给处于延迟关键路径上的线程,另一个用于延迟敏感度较低的工作。线程具体归入哪个池,由策略内部编码的领域知识来决定。每个池的大小会根据负载情况进行动态调整。这种做法倾向于让相互关联的工作长时间运行在同一组 CPU 上,从而提升末级缓存(L3)的命中率,减少对高成本 DRAM 访问的依赖。
该策略被打包为一个用户态二进制程序,负责加载 BPF 程序。这种设计大大加快了实验和性能调优的节奏。要上线一个新版本,只需重启调度器进程即可卸载旧策略、加载新策略,无需重新编译或重装内核。
成果与影响
初次上线是将最大型号的广告投放服务器,从使用 CFS 调度器的内核 6.4 切换到搭配 sched_ext 的内核 6.9。基于回测实验的结果,本次上线带来了以下收益:
- 加权广告排序指标(衡量广告检索与排序数量的指标)提升 1.1%。
- 集群整体节省 3.28 兆瓦电力。
- 广告检索链路服务端 p99 延迟降低 28%2。
持续叠加的改进。后续两项调度策略更新完全以用户态改动的方式交付,进一步扩大了这一收益:
- 服务端 p99 延迟再降 60%。
- 关键链路上的超时错误减少 18%。
这是一项无需依赖内核版本发布即可取得的实质性收益。前面提到的每一轮后续迭代,从立项到上线只需几天而非几个月,因为调度策略以 BPF 程序的形式存在于用户态。正是这样的迭代节奏,让 sched_ext 从"解锁内核升级"演变为广告投放服务的持续优化平台。

从短期方案升级为战略资产
最初只是为了解决某个具体运维问题而启动的工作,最终展现出的战略价值和普适性远超我们的预期。sched_ext 为 Meta 带来了几项关键收益:
并行且解耦的调度优化路径。上游 Linux 调度器会随时间自然演进,有时步伐较大(例如从 CFS 迁移到 EEVDF),这可能对下游使用者造成冲击。sched_ext 让 Meta 能够在持续演进的过程中,灵活地不断改进这些定制调度器。我们运行并持续打磨自研的基于 BPF 的调度逻辑,使其贴合生产工作负载的独特需求,从而无论上游发生什么变化,关键服务都能保持最优状态。
独立部署,开销更低。调度改进以 BPF 程序更新的形式发布,从开发到上线只需几天而非几个月。实验成本的下降带来了变革性的影响:过去需要打内核补丁并经过长达数月验证的想法——比如本地缓存感知的放置、基于 ROI 的执行单元路由、NUMA 感知的调度——如今变成了可快速推进的迭代项目,而不再是需要长期投入的大工程。
整个行业的共享成果。sched_ext 已被合入 Linux v6.12 内核主线,因此 Meta 此次采用的同一套机制现在可供整个 Linux 生态使用。任何运行负载无法套用通用调度模型的运维方——无论是超大规模云服务商、云提供商,还是嵌入式系统团队——都可以在不 fork 内核的前提下,交付针对自身负载定制的调度策略。
未来规划
sched_ext 已经让我们看到了进一步提升广告服务性能的契机:它让应用程序能够对调度器的行为施加更精细的控制。例如,广告服务清楚各服务请求之间的相对重要性,当某个线程开始处理重要请求时,它完全可以向调度器发出提示。调度器收到该提示后,便可相应地采取措施,比如延长该线程的调度时间片,或确保它始终排在队列最前面。
致谢
特别感谢 Samuel Nair、Usama Arif、GP Musumeci、Praveen Alevoor、Ye Wang,以及更广泛范围内的广告容量效率团队和内核团队的贡献与协作。
广告基础设施领导团队:Uladzimir Pashkevich、Varna Puvvada、Prabhakar Goyal、Neeraj Agrawal、Tak Yan、Liz Shepherd、Drew Lackman