我有一个气流dag,可以提取数据并执行验证。如果验证失败,则需要重新运行提取。如果验证成功,则继续。
我读过人们说子洼可以解决这个问题,但我看不出这方面的任何例子。我尝试过使用子dag,但遇到了与尝试在一个DAG中进行操作相同的问题。
如果其中一个任务失败,我怎样才能让Sub DAG中的所有任务重新运行?
我有以下DAG / sub dag详细信息:
maindag.py
default_args = {
'owner': 'airflow',
'depends_on_past': False,
'start_date': start_date,
'retries': 3,
'retry_delay': timedelta(minutes=5),
'sla': timedelta(hours=sla_hours)
}
main_dag = DAG(
dag_id,
default_args=default_args,
schedule_interval='30 14 * * *',
max_active_runs=1,
concurrency=1)
task1 = BashOperator(...)
task2 = SubDagOperator(
task_id=sub_dag_task_id,
subdag=sub_dag(dag_id, sub_dag_task_id, start_date, main_dag.schedule_interval),
dag=main_dag)
task3 = BashOperator(...)
subdag.py
def sub_dag(parent_dag_name, task_id, start_date, schedule_interval):
dag = DAG(
'%s.%s' % (parent_dag_name, task_id),
schedule_interval=schedule_interval,
start_date=start_date,
)
task1 = BashOperator(...)
task2 = BashOperator(...)
task3 = BashOperator(...)
task1 >> task2 >> task3
return dag
在子dag中,如果任务3失败,我希望任务1再次运行,即使它已成功。为什么这么难做?!
答案 0 :(得分:3)
我通过在主dag中创建重试回调方法找到了解决方法:
(原始来源:https://gist.github.com/nathairtras/6ce0b0294be8c27d672e2ad52e8f2117 )
from airflow.models import DagBag
def callback_subdag_clear(context):
"""Clears a subdag's tasks on retry."""
dag_id = "{}.{}".format(
context['dag'].dag_id,
context['ti'].task_id
)
execution_date = context['execution_date']
sdag = DagBag().get_dag(dag_id)
sdag.clear(
start_date=execution_date,
end_date=execution_date,
only_failed=False,
only_running=False,
confirm_prompt=False,
include_subdags=False)
然后,对于运行subdagoperator的任务,它有:
on_retry_callback=callback_subdag_clear,
它现在清除每个任务的任务实例历史记录,并重新运行子dag中的每个任务,直到主dag中的重试次数。
答案 1 :(得分:1)
有一个更简单的选择。 Full snippet
代替
dag_id = "{}.{}".format(
context['dag'].dag_id,
context['ti'].task_id
)
sdag = DagBag().get_dag(dag_id)
你可以做
task = context['task']
sdag = task.subdag
为什么?
因为(很可能)您的任务与具有subdag属性的SubDagOperator有关。
我在使用solution by Alistair时遇到了问题。当我尝试在sdag变量上调用clear时,会得到一个异常,因为它是None。
我细查了这个问题,以至于在填充DagBag时无法正确解析Dags,我无法弄清楚。相反,我通过查看上下文中传递的内容并发现它具有对具有subdag属性的任务的引用(只要它来自SubDag运算符)而找到了一种解决方法