AI INSIGHT

Lyft将流式计算集群迁移到Apache Flink Kubernetes Operator

行业活动 InfoQ 2026-10-20 17:06
AI 摘要

点击查看原文>

Lyft 淘汰了其内部开发的 Flink operator,其原因包括每次 Flink 升级都需要进行维护,以及自动伸缩和回滚方面存在的缺陷。

Lyft 已经将数百个生产环境的Apache Flink Job 从自研的Kubernetes operator迁移到了Apache Flink Kubernetes Operator。在最近发布的Lyft Engineering文章中,流计算工程师Maheep Myneni、Arda Kuyumcu与 Prem Santosh Udaya Shankar 表示,此次迁移在集群范围内解锁了基于上次状态(last-state)进行升级、原地自动伸缩与资源自动调优功能。

Lyft 在 2020 年构建了自研的 Operator,当时开源社区还没有为在 Kubernetes 上运行的 Flink 构建专用的控制平面。双部署(dual-deployment)升级会启动第二个集群、创建保存点(Savepoint)、取消旧 Job 并从该保存点恢复。遗留 Operator 的 BlueGreen 模式会在工程师手动切换流量之前保持两个集群同时运行。

原有的保存点触发器既没有重试逻辑,也不具备幂等性。对于较大状态的 Job,如果发生超时且没有可用的最近检查点(Checkpoint),就会导致部署失败,或者使 Job 在完全没有状态的情况下重启。此外,非 JVM 内存的预留仅由一个 systemMemoryFraction 参数来控制,这本质上是对Apache Beam Python 运行环境所需额外开销的一种粗略估计。如果该值设置过低,TaskManager 就会因内存溢出(OOM)被系统杀掉,如果设置过高,整个集群又会白白浪费内存。

Apache Flink Operator 将基于上次状态(last-state)恢复作为第一等的升级模式,即使 JobManager 处于不健康状态,也能从高可用的元数据或最新的检查点进行恢复。为了避免重写 Jsonnet 模板,Lyft 的部署 API 在边界层将遗留的 FlinkApplication 规格自动转换成了 FlinkDeployment 资源。这一转换层将 jarName 映射为 jarURI,将节点选择器提取并转换为 PodTemplateSpec 对象,注入了遗留的环境变量,并将升级策略默认设为从上次状态恢复。

Apache Operator 会优先启动 JobManager,以便管理 TaskManager 的生命周期。在弃用旧版 Operator 的同时,Lyft 也将“双部署(dual deployments)”模式替换为了“先停后启(stop-then-start)”的部署模式。这导致常规部署会产生 3 到 6 分钟的停机时间,而大型 Job 的停机时间则长达约 20 分钟。为此,Lyft 引入了 FlinkBlueGreenDeployment(一种自定义资源定义,CRD)。在 Lyft 开始测试时该功能仍在开发中,随后于 2026 年 2 月 15 日随 Operator 1.14.0 版本正式发布。它允许新旧版本在切换前并行运行。在遇到了一个被追踪为FLINK-38548的配置重命名缺陷后,Lyft 贡献了上游修复代码。Myneni、Kuyumcu 和 Udaya Shankar 这样写到:“当我们发现这个蓝绿部署的缺陷时,我们提交了 Issue,几天内修复代码就被合并到了上游。”

为了实现自动扩缩容,Lyft 将 Flink 升级到了 1.19 版本。在 1.17 版本中,修改并行度需要重启 Job,而那些最需要扩缩容的 Job 往往无法承受这种中断。Operator 的文档指出,从 Flink 1.18 开始支持原地扩缩容。升级到 1.19 版本还解锁了独立发布的 KinesisStreamsSource(该组件于 2024 年 11 月随 flink-connector-aws 5.0.0 版本发布,并且要求 Flink 1.19 或更高版本)。它像 Kafka Source 一样为 Kinesis 流提供记录积压(backlog)指标,从而为自动扩缩容器提供了此前在 Kinesis 绑定 Job 中缺失的信号。随后,自动调优(Autotuning)回收了 Beam Python 进程仍在占用的 JVM 开销,但这导致 Beam 集群会再次发生 OOM,直到 Lyft 将该运行环境迁移到具有独立资源限制的专用 Sidecar 容器中才解决了问题。

由于自动调优会调整容器内存大小并需要重启 Pod,它与原地自动扩缩容存在冲突。Lyft 按业务关键性对功能进行了拆分:定价和路由 Job 使用不带自动调优的原地扩缩容,而关键性较低的工作负载则允许通过重启来调优资源。当基于重启的自动扩缩容触发 Pod 迁移时,一个自定义的最大分配调度器(most-allocated scheduler)会将它们高密度地打包,这使得 Lyft 能够下线利用率不足的节点,同时由Karpenter按需配置 EC2 算力。

Spotify的Flink Operator是从谷歌现已废弃的 Operator 分支而来,它的文档同样记录了将 Beam Python SDK harness 作为 Sidecar 容器与 Flink TaskManager 并排运行的做法,这与 Lyft 在经历自动调优导致的 OOM 后最终所采用的架构不谋而合。Amazon Managed Service for Apache Flink能够托管检查点并免除 Operator 的维护工作,但它缺乏 Pod 级别的 Sidecar 自定义能力。

相比之下,Netflix目前同时运行着其内部自研的Flink Autoscaler和开源版本,并正在逐步向后者收敛,而不是采用 Kubernetes Operator。Netflix 运行着超过 30000 个 Flink Job,而 Lyft 只有数百个。Lyft 的流计算团队接下来希望实现更快的市场定价循环以及自动驾驶车辆的遥测数据处理。Myneni、Kuyumcu 和 Udaya Shankar 这样写到:“自动扩缩容器正如我们所期望的那样运作,它对一个此前每年被过度配置了数百万美元算力的集群进行了合理的规模调整。”

查看英文原文: Lyft Moves Streaming Fleet to Apache Flink Kubernetes Operator

来源:InfoQ
阅读原文