Pinterest为何迁移到新的大数据处理工作流平台Apache Airflow?


在这篇文章中,我们将解释我们如何处理和设计将旧系统迁移到Apache Airflow、以及与我们所有的工程师团队协调以将 3000 多个工作流无缝迁移到 Airflow。
 
Pinterest 的理念始终以数据为中心。作为一家数据驱动的公司,这意味着所有摄取的数据都将被存储以供进一步使用。这看起来像是每天600 TB的新数据,包含超过500 PB的总数据。在这种规模下,大数据工具在使我们公司能够收集有意义的见解方面发挥着关键作用。这就是工作流团队的用武之地。我们帮助促进了 4000 多个工作流,这些工作流平均每天产生 10,000 次流程执行和 38,000 次每日作业执行。
 
早在 2013 年,Pinterest 就构建了一个名为Pinball的内部调度程序框架。该解决方案适合当时公司的需求,但无法随着需求的增加而扩大规模,从而为内部和外部的其他产品和服务提供服务。
 
2019 年,我们对 Spotify 的Luigi、LinkedIn 的Azkaban和一些替代方案进行了初步分析,但我们最终还是选择了 Apache 的Airflow,原因如下:

  • 目标对齐:我们的用户要求的功能要么已经内置在 Airflow 中,要么可以添加到当前的版本中。
  • 行业:它被许多组织广泛采用,有一个活跃的社区承诺,促进大量讨论,并有很好的文档供我们的用户查看。
  • DSL:它是基于 python 的,与我们之前的系统保持一致,我们的用户将在这里减少差异。
  • 代码:Airflow 是用模块编写的,因此更容易使用单独的组件来连接自定义部件。
  • 可扩展性:它包含重启可以恢复的无状态组件,UI 从中央数据库中提取,并允许我们为我们的 kubernetes 基础设施和可分区调度程序插入主要部分。
  • 声誉:总体而言,社区似乎对 Airflow 的产品感到满意

 

按照我们的标准,成功迁移过程的关键是:

  • 了解并填补 Airflow 与我们之前拥有的内部工作流系统之间的差距。我们确定了功能差距、安全差异以及用户习惯的术语。
  • 提供迁移工具,以低成本方式同时大规模迁移多个工作流并进行验证。
  • 拥有清晰和持续的用户沟通和入职材料,例如 wiki、培训课程、积极的用户支持和公告。
  • 启用无状态 UI 调度程序分区,并启用 Kubernetes 集成以提供定制和可扩展的解决方案。
  • 拥有清晰的 CI/CD 管道,使系统保持一致、可靠和高效,以维护多个基础架构分支。
  • 严格测试——单元测试和集成测试都在暂存环境中进行,以防止破坏性更改并采取谨慎的部署方法。
  • 维护运行状况检查和综合指标,并在负载增加时发出警报以进行微调。

 
需要注意的最重要的一点包括:
  • 确保计划在迁移前后保持一致。以前系统和 Spinner 系统的调度间隔并不总是一致,因为定义调度程序的方式不同(旧系统并非完全基于 cron)。因此,防止误跑和超跑。
  • 为每个任务配置资源,例如内存设置,以防止任务在启动前失败。
  • Kubernetes pod 的预热成本不是我们预期的。pod 启动延迟确实有一个重要的成本,对于您的团队用例来说,它必须是总体上可以接受的。
  • Kubernetes pod 冗余边车可能会因网络问题而增加延迟,并且可能会为您的工作流程增加调度延迟。
  • 对用户教育和支持的投资可能很高。
  • 维护旧 DSL 和新 Airflow DSL 的混合解决方案增加的成本开销是不小的。

 
方法和要求
我们的平台已将我们的迁移要求定义为:
  1. 需要最少的用户代码更改
  2. 迁移时不间断地执行生产工作流程
  3. 为旧系统设置一个日期并完成弃用

鉴于这些,我们可以通过两种主要方式进行此迁移:
  1. 请求工作流所有者在 Airflow DSL 中重写他们的旧工作流,并在此过渡过程中为他们提供支持
  2. 平台提供了直接进行 DSL 翻译的工具

使用方法 1,它将减少我们和用户的技术债务,并且平台不必维护额外的基础设施,但由于所有定制的用户逻辑和依赖项都放入了传统的 Pinball 作业,因此存在一些重大挑战。即使没有这些挑战,我们也没有在这个提案中得到客户的支持,因为每个团队的成本将是太多的工程时间。最后,这可能会推迟旧系统的弃用,因为我们需要依靠我们的客户来完成工作,这使得它不可行。
因此,我们的方法被证明更接近方法 2——我们在 Airflow 调度程序中构建了一个迁移层,它在动态解析 dag 文件期间将旧工作流系统中的工作流定义转换为 Airflow 有向无环图 (DAG)。这意味着不会有任何用户代码更改和最少的用户参与,为用户提供透明的迁移体验。旧工作流中的每个作业都被转换为专门实施以支持工作流迁移用例的包装器运算符类型。在执行期间,操作员启动一个新的 k8s pod,该 pod 使用旧系统的映像启动旧作业的实际逻辑。通过这种方式,我们可以为翻译任务模拟遗留系统的执行环境。