情况: Airflow 1.10.3 在 Kubernetes pod 上运行,LocalExecutor,parallelism=25 每天晚上,我们的 DAG 将开始它们的预定运行,这意味着许多任务将并行运行。每个任务要么是在另一个 Pod 上开始实际工作的 KubernetesPodOperator,要么是等待另一个任务完成的 ExternalTaskSensor(在 ETL DAG 中)。
问题: 启动的每个任务将创建另外 2 个本地进程(除了工作进程),每个进程占用 70MB。但所有这些进程都在等待,要么等待另一个 Pod (KubernetesPodOperator) 完成,要么等待另一个任务完成 (ExternalTaskSensor)。这是一个巨大的内存开销,似乎过分了。我们明确地选择了这个设置来将资源负载放在其他地方 (Kubernetes) 并使用 Airflow 轻量级:仅用于调度其他 pod。我们未来的增长意味着我们希望在 Airflow pod 上扩展到数十个甚至数百个并行任务,但这在这些内存要求下不太可行。
问题:
对此我们能做些什么?是否有设置可以减少每个并行任务的内存开销?也许在工作进程中运行 Operator?欢迎任何建议,谢谢!
(也许答案是:这就是 Airflow 的工作方式,在这种情况下:有没有更轻量级的调度解决方案的替代方案?)
我们已经尝试过:
- 使用传感器“重新安排”模式而不是“戳”,以免传感器在等待时占用资源。是否导致任务卡在 up_for_reschedule 中。
- 玩并行度设置,但最终我们需要很多进程,所以这个值需要非常高。
PS 这是我关于 SO 的第一个问题,因此欢迎改进/要求提供更多信息,谢谢!
更新
我知道 LocalExecutor 在这样的专业版中不能很好地工作。如果您有资源繁重的任务,比如 Airflow 操作员,那么切换到分布式设置是有意义的。但我一直认为我们的设置既有魅力又有纯粹的工作流程设置:只有 1 个 Airflow pod,它只安排其他 pod 并等待它们完成。使用 JVM 设置意味着很多线程大多处于空闲状态,等待 IO。一个 JVM 线程的开销大约是每个线程 1 MB,而使用 Airflow,我们每个任务必须处理 140MB!我可能会尝试创建一个 LocalThreadedExecutor ,它不会启动额外的进程......
这是 LocalExecutor 的固有问题。它基于分叉流程。即使任务只是触发启动另一个 pod,对于每个任务 Airflow 仍然会调度一个进程,这当然会产生很高的开销。
我的建议是转向 Kubernetes 执行器https://airflow.apache.org/docs/1.10.1/kubernetes.html。然后每个任务都会自动作为 Pod 运行。然后,您不再需要显式使用 KubernetesPodOperator,而只需使用常规 Airflow 运算符,因为它们无论如何都会作为 Kubernetes 中的 Pod 执行。最后,如果这是一种可行的方法,我认为从长远来看它将带来最好的结果。
| 归档时间: |
|
| 查看次数: |
1957 次 |
| 最近记录: |