Netflix 的双 Flink 自动扩缩容实践:从自建到开源的迁移之路
如今,Netflix运行着两台Flink自动缩放器。这正好比我们想要的多一个。我们多年前就自己建了第一台,当时还没有适合我们平台的成熟方案。
第二个来自Apache Flink社区,它能够扩展我们自制系统从未设计过的工作负载。我们现在两者都在生产环境中运行,并且正稳步向开源版本汇聚。
在这个过程中,我们学到了关于指标、成本以及维护基础设施的实际成本的严峻经验教训,我们希望无论你运行的是少数几个Flink项目还是数万个项目,这些经验都能有所帮助。
为什么在我们这个尺度上,自动缩放不是可选的
Netflix 自 2017 年起就在 Apache Flink 上运行流处理。截至2026年,我们在多个AWS区域运营超过3万个Flink任务。大多数不是手动部署;它们由我们的托管平台生成数据网格,所以大多数用户从未直接接触过Flink的任务。
较少但不断增长的部分是定制工作,由公司各团队为个性化、广告和现场活动等用例开发和运营。它们从单操作员作业(在Kafka主题间穿梭记录)到有状态的流水线(包含分支、连接和状态数,以及每日周期、启动和区域故障切换)的负载波动。
为高峰期提供所有这些岗位是浪费;平均配置会导致浪涌期间的延迟。在我们的平台上,缩放动作并非免费:默认情况下,它意味着取一个存档点,优雅地停止工作,然后以新大小重启,而对于大型有状态作业来说,这可能需要几分钟时间。
这就留下了一个真正棘手的问题:如何在每个工作需要时提供所需的资源,既不依赖人工,也不破坏任何东西?
第一台自动对比器:从外部观察
我们的第一个解决方案是在2019年左右开发的,是一个自动缩放器,形状类似流处理作业。它继续下去螳螂,实时接收来自的集群级指标阿特拉斯,我们的遥测平台,包括CPU、网络、Kafka延迟、输入速率和消耗速率信号,适用于每个任务。
扩展器结合了延迟驱动的追赶时间、CPU/网络利用阈值、观察到的性能历史以及对近期输入速率的回归,决定何时扩展,或由较小集群是否能处理前瞻窗口。
由于自动扩展器独立于Flink平台运行,因此不受Flink内部问题的影响。把它当作流媒体工作来构建也让它更容易扩展。每个自动缩放节点都处理Flink部分作业的指标,我们从未需要编写自定义分片或协调逻辑来跟上不断增长的Flink车队。
它可靠地将数千条管理管道的资源使用减少了25%至45%。请查看我们之前的演讲Flink Forward 2020.
但从外面看是有天花板的。系统通过粗略的容器指标推理整个集群,并对一个旋钮——TaskManager总计数进行扩展,使作业中的每个操作员都一起移动。
这符合其设计的简单单操作员流程,但不符合团队越来越多地为广告、推荐和游戏带来的多操作员、有状态的DAG。这些正是它无法推理的工作,支持每个新机壳意味着更多自定义逻辑,而非通用能力。
自动缩放器的表现取决于其底层外部系统所提供的指标。这些指标可能会漏掉真正的问题:一个作业可能完全忙碌,却没有显示为CPU利用率,导致作业陷入退化状态,缩放器无法察觉。
最近一次网络迁移悄然改变了部分流量的报告方式,而该扩展器依赖的Atlas指标子集也停止了准确捕捉所有数据。这一空白一直隐形,直到很久以后才在生产中浮现。
是时候重新考虑了建造对抗买.
第二台自动比例器:内部推理
刚开始时,Flink社区还没有成熟的自动缩放器可供使用。等我们重新评估时,情况已经变了:Apache Flink 自动分流器.它不再从外部观察集装箱,而是从工作内部推理。

其核心思想是估计每个算符的真实处理率(TPR):如果完全忙碌,它能维持的吞吐量。Flink会报告每个子任务中实际工作时间的比例,与背压或闲置时间分开。
将观察吞吐量除以该繁忙比例,可将容量外推为满载利用率:一个操作员在忙碌70%的时间处理700条记录/秒时,TPR为700 / 0.7 = 1000条记录/秒。
从源出发,自动标度器会游走作业图,利用每个算子的TPR、输入/输出比和目标利用率计算每个顶点所需的并行度,从而避免任何算符成为瓶颈,而不是将整个集群作为一个整体调整大小。

这两种方法形成了不同的契约,下面将总结。

对我们来说,决定性区别在于最后两行:OSS自动缩放器能够精确扩展我们自制系统无法做到的有状态、多操作员作业,并且允许每个作业拥有自己的配置——稳定期、阈值以及根据工作负载调整的其他缩放行为。
这使得它非常适合团队手工定制的定制任务。
让它在Netflix规模下运作
采用算法很直接;社区已经完成了最难的部分。我们的工作是要在自己的工作中可靠地运行它,这也是我们的系统与开源部署最大的不同之处。
首先OSS 自动缩放器最初设计为驻留在 Flink 的 Kubernetes 操作符中,但我们的 Flink 平台运行在独立的控制平面上,而不是该操作员(参见我们之前的演讲2024年当前会议).社区后来做出了一个极好的决定,将核心逻辑保留为独立库。
他们重构了四个通用接口,使得直接插入我们内部生态系统变得轻松:一个承载作业元数据和REST API信息的上下文、一个状态存储、一个事件处理程序,以及一个应用扩展决策的实现器。
该服务是一个运行在临时,持久工作流程引擎。编排器工作流大约每分钟轮询一次 Flink 控制平面,针对启用自动缩放的作业,并为每个作业启动一个长期运行的工作流。
每个每个作业的工作流程从其 Flink JobManager 中提取该作业的每个顶点指标,运行 OSS 评估算法,并在缩放决策结果后,将其交给实现者这通过我们的Flink控制平面实现了变化。

按工作流程设计是对疼痛的直接回应。我们首先在单个批次循环中对整个作业集进行了评估,结果非常脆弱:一个缓慢或异常的作业都可能阻碍其后面所有作业的指标收集和扩展。
给每个作业单独的持久工作流隔离了爆炸半径,因此单个有问题的作业会失败并自行重试,随着更多作业的上线,运行时间会扩展。
其次,“社区作品”与“Netflix规模作品”之间存在三个工程空白:
- 高并行度量收集。在大型任务中,从 JobManager 拉取指标成了瓶颈,部分原因是 Flink 的运行时。为此,我们改成了JobManager缓存暂时指标名称并清理一次,而不是每次取数据都重新扫描,同时增加了服务器端过滤功能,自动扩展器只要求输入所需的指标。这使得自动扩展器能够处理多达3000个Flink子任务的作业,而之前它在大约1000个子任务上表现挣扎。这些内容在我们内部分支的 Flink 发布中,而有些则是在上游贡献的,比如弗林克-36172.
- 保持前向链式。两个由 a 连接的独立顶点前进连接必须以相同的并行性运行,因为记录是在固定的本地通道内存中传递的。单独攀爬其中一个,Flink就不会失败;它会悄无声息地将该边缘转换成网络洗牌。我们的叉检测前连通子图,并将每个子图作为一个单元进行缩放。
- 尊重水槽的极限。有些吸收的写入能力有限,因此我们增加了异步-吸收回压检测(也包括叉式调整),以防止自动扩展器将作业扩展到无法吸收更多内容的吸收槽。
在启动任何东西之前,实现者会进行一系列安全检查。例如,在公司范围内的区域故障切换期间,它拒绝在撤离区域中缩减岗位。它还会验证新集群是否有足够的磁盘来保存作业的检查点状态,并为较大的集群添加一个小型备用缓冲区。
走向一个自动成比例机的道路
去年,基于开源软件的自动扩展器在Netflix实现了定制任务的全面可用性,带来了良好的初步成果。例如,我们的客户遥测和日志团队实现了58%的年化Flink计算支出减少,每年节省约110万美元。
这种效率由三个关键因素驱动。首先,静态配置必须始终考虑峰值负载,而自动扩展则动态适应每日周期,捕捉夜间和周末流量相较工作日峰值的下降。
其次,自动扩展器不再依赖团队在性能提升或节后放缓后手动优化资源,而是持续调整容量。最后,采用统一的容器尺寸可以实现更优越的箱装和更细粒的缩放增量。
此外,过于急切地缩放本身就是陷阱。如果砍得太深,CPU 会过饱和、卡顿激增,系统无法立即响应,因为每次重启后都要重建度量窗口和稳定期。
我们现在的目标利用率为0.45,低于社区默认值0.7,故意用一些效率换取稳定性。较少且更平静的重新调整对于大型国家岗位来说,边际成本是值得的。
虽然我们的缩放器为有状态DAG提供了细粒度信号和顶点级决策单元,但快速重新标放仍然高度依赖于Flink核心的状态恢复性能。如今,扩展有状态作业的最大剩余成本不是缩放者的逻辑,而是重启和状态恢复过程本身。
Flink 2 通过其拆分状态架构,将状态保存在外部存储中而非本地磁盘,这可以大幅减少重新扩展或恢复对总状态大小的依赖。我们已开始在Netflix支持Flink 2.2,计划对这个新的状态后端进行实验,看看它是否能帮助消除大型有状态作业扩展时的状态恢复瓶颈。
展望未来,我们计划将所有内部扩展器用例迁移到基于开源软件自动缩放器的新版本,以简化运营覆盖面积。
主要要点
在此过程中,有三个超越Flink的教训:
- 指标的选择比算法的复杂性更重要。我们最有用的调试很少是关于缩放数学;而是关于最信任哪个信号。在调整算法之前,先了解你的指标。
- 设定合理的默认值,但留有调整空间。我们的托管工作足够相似,一个好的默认设置覆盖了大部分未被修改的任务,这正是平台的意义所在。但强制每个任务都用单一配置会惩罚不合适的配置,因此我们将默认配置与每个任务覆盖匹配,并故意隐藏需要深度专业知识的旋钮。大多数团队根本不需要考虑自动比例器。
- 先收养,再延伸。我们内部构建是因为2019年没有成熟的作品适合我们的平台。当一个强大的社区项目出现时,正确的做法既不是永远捍卫我们的投资,也不是一夜之间将其拆除,而是将其用于新工作负载,贡献修复,并规划有序的迁移。
感谢Flink和Data Mesh团队为这项工作所依赖的控制平面变更,感谢Temporal团队和我们早期的试点团队,以及我们建立基础的Apache Flink自动扩展器维护者。
特别感谢张安迪、张凯文、丹尼尔·特雷格、吉尔·皮雷斯、马克·赵、马修·科尔尼茨基、尼基尔·苏莱冈、苏杰·贾恩和汤姆·李。
两个闪烁自动缩放器的故事最初发表于Netflix 技术博客在Medium上,人们通过突出和回应这个故事,继续讨论。