Airflow 1.10.3即使并发度为8,子DAG也只能并行运行1个任务
最近,我将气流从1.9升级到1.10.3(最新版本) 但是,我确实注意到一个与SubDag并发相关的性能问题。子DAG中只能拾取1个任务,这不是它应该的方式,子DAG的并发设置是8 见下文:Airflow 1.10.3即使并发度为8,子DAG也只能并行运行1个任务,airflow,directed-acyclic-graphs,airflow-scheduler,Airflow,Directed Acyclic Graphs,Airflow Scheduler,最近,我将气流从1.9升级到1.10.3(最新版本) 但是,我确实注意到一个与SubDag并发相关的性能问题。子DAG中只能拾取1个任务,这不是它应该的方式,子DAG的并发设置是8 见下文: get\u monthly\u summary-214和get\u monthly\u summary-215是两个子dag,可以由父dag并发在并行控制器中运行 但是,当放大子页面时,说获取每月摘要-214,然后 您可以肯定地看到,一次只运行一个任务,其他任务都在排队,并且它一直以这种方式运行。当我们检
get\u monthly\u summary-214
和get\u monthly\u summary-215
是两个子dag,可以由父dag并发在并行控制器中运行
但是,当放大子页面时,说获取每月摘要-214
,然后
您可以肯定地看到,一次只运行一个任务,其他任务都在排队,并且它一直以这种方式运行。当我们检查SubDag并发时,它实际上是8,正如我们在代码中指定的:
我们确实设置了池插槽大小,它是32,我们确实有8个芹菜工人来处理排队的任务,我们与并发相关的气流配置如下所示:
# The amount of parallelism as a setting to the executor. This defines
# the max number of task instances that should run simultaneously
# on this airflow installation
parallelism = 32
# The number of task instances allowed to run concurrently by the scheduler
dag_concurrency = 16
# The app name that will be used by celery
celery_app_name = airflow.executors.celery_executor
# The concurrency that will be used when starting workers with the
# "airflow worker" command. This defines the number of task instances that
# a worker will take, so size up your workers based on the resources on
# your worker box and the nature of your tasks
worker_concurrency = 16
dag = DAG(
dag_id=DAG_NAME,
description=f"{DAG_NAME}-{__version__}",
...
)
with dag:
ur_operator = sub_dag_operator_with_default_executor(
task_id=f"your_task_id",
subdag=load_sub_dag(
parent_dag_name=DAG_NAME,
child_dag_name=f"your_child_dag_name",
args=args,
concurrency=dag_config.get("concurrency_in_sub_dag") or DEFAULT_CONCURRENCY,
),
queue="mini",
dag=dag
)
此外,所有子DAG都是使用名为mini
的队列配置的,而其所有内部任务都是名为default
的默认队列,因为如果在同一队列上同时运行子DAG操作符和子DAG内部任务,我们以前可能会遇到一些问题。我还尝试对所有任务和操作员使用default
队列,但没有帮助
旧版本1.9似乎很好,每个子DAG可以并行执行多个任务,我们遗漏了什么吗?这是因为在Airflow 1.9.0中,子DAG操作符使用了默认的执行器 气流1.9.0: 但是,从Airflow 1.10及以后,SubDagOperator的默认执行器更改为SequentialExecutor 气流>=1.10: 改变它的提交是 更改的详细原因可在中找到 我们应该将subdag_运算符的默认执行器更改为SequentialExecutor。subdagoperator不支持气流池,因此它可能会消耗所有工作人员资源(例如celeryExecutor)。这会导致airflow-74中提到的问题,并限制subdag_操作符的使用。通过使用顺序执行器指定,我们在生产中使用subdag_运算符
根据上面发布的@kaxil的发现,如果您仍然希望在子DAG内并行执行任务,一个变通解决方案是创建一个包装函数,以便在构造
子DAG操作符时显式传递执行器
:
from airflow.operators.subdag_operator import SubDagOperator
from airflow.executors import GetDefaultExecutor
def sub_dag_operator_with_default_executor(subdag, *args, **kwargs):
return SubDagOperator(subdag=subdag, executor=GetDefaultExecutor(), *args, **kwargs)
创建子dag操作符时,使用默认执行器调用子dag操作符。为了缓解子dag操作员的压力
我们应该将subdag_运算符的默认执行器更改为SequentialExecutor。subdagoperator不支持气流池,因此它可能会消耗所有工作人员资源(例如celeryExecutor)。这会导致airflow-74中提到的问题,并限制subdag_操作符的使用。通过使用顺序执行器指定,我们在生产中使用subdag_运算符
我们建议创建一个特殊队列(在我们的例子中,我们指定queue='mini'和芹菜工人来处理subdag_操作符,这样它就不会消耗普通芹菜工人的所有资源。详情如下:
# The amount of parallelism as a setting to the executor. This defines
# the max number of task instances that should run simultaneously
# on this airflow installation
parallelism = 32
# The number of task instances allowed to run concurrently by the scheduler
dag_concurrency = 16
# The app name that will be used by celery
celery_app_name = airflow.executors.celery_executor
# The concurrency that will be used when starting workers with the
# "airflow worker" command. This defines the number of task instances that
# a worker will take, so size up your workers based on the resources on
# your worker box and the nature of your tasks
worker_concurrency = 16
dag = DAG(
dag_id=DAG_NAME,
description=f"{DAG_NAME}-{__version__}",
...
)
with dag:
ur_operator = sub_dag_operator_with_default_executor(
task_id=f"your_task_id",
subdag=load_sub_dag(
parent_dag_name=DAG_NAME,
child_dag_name=f"your_child_dag_name",
args=args,
concurrency=dag_config.get("concurrency_in_sub_dag") or DEFAULT_CONCURRENCY,
),
queue="mini",
dag=dag
)
然后,当您创建特殊芹菜工作程序(我们使用的是轻量级主机,如2核和3G内存)时,将气流\uuuuu芹菜\uuuu默认\u队列指定为mini
,这取决于您希望并行运行的子dag操作符的数量,您应该创建多个特殊芹菜工作程序以负载平衡资源,我们建议,每个特殊芹菜工人一次最多照顾2个副dag操作员,否则将耗尽(例如,2核和3G内存主机上的内存不足)
此外,您还可以通过在airflow UIVariables
配置页面中创建的ENV VARconcurrency\u in_sub\u dag
来调整子dag内部的并发性
更新[22/05/2020]上述仅适用于气流(=1.10.0)
对于beyone 1.10.3,请使用
from airflow.executors import get_default_executor
相反 谢谢!。
我对最新版本(1.10.5)GetDefaultExecutor的代码做了一些修改,使其不再工作:
from airflow.executors.celery_executor import CeleryExecutor
def sub_dag_operator_with_celery_executor(subdag, *args, **kwargs):
return SubDagOperator(subdag=subdag, executor=CeleryExecutor(), *args,
**kwargs)
谢谢,我想你是对的,我发现这里的差异也限制了subdag操作符的使用,很遗憾。非常有帮助。注意:从1.10.4GetDefaultExecutor
被重命名为get\u default\u executor
顺便说一句,所有跳过的错误在1.10.5中得到了修复,这意味着使用子DAG
的原因之一已被删除,多亏了很多。包括get_default_executor
import,在函数sub_default_executor\U中使用executorexecutor=get_default_executor()
中使用带有_default_executor的sub_dag_操作符,并使用该函数代替subdag操作符解决了问题。您仍然可以使用默认executor作为“from.executors import get_default_executor”。如果celeryExecutor()不适合