Airflow 如何设置多运算符dag,以便在运行实例的所有任务完成之前不会实例化另一个实例?

Airflow 如何设置多运算符dag,以便在运行实例的所有任务完成之前不会实例化另一个实例?,airflow,apache-airflow,airflow-scheduler,Airflow,Apache Airflow,Airflow Scheduler,我们的气流实现中有多个操作员DAG。 假设dag-a有运算符t1、t2、t3,它们被设置为按顺序运行(即t2依赖于t1,t3依赖于t2) 我们需要确保在实例化dag-a时,在实例化同一dag的另一个实例之前(或在触发下一个dag实例上的第一个任务之前),它的所有任务都会成功完成 我们在DAG中设置了以下内容: da['depends_on_past'] = True 现在发生的是,如果实例化的dag没有任何错误,我们将看到所需的效果。 然而,假设dag-a计划每小时运行一次。按计划触发dag-

我们的气流实现中有多个操作员DAG。 假设dag-a有运算符t1、t2、t3,它们被设置为按顺序运行(即t2依赖于t1,t3依赖于t2)

我们需要确保在实例化dag-a时,在实例化同一dag的另一个实例之前(或在触发下一个dag实例上的第一个任务之前),它的所有任务都会成功完成

我们在DAG中设置了以下内容:

da['depends_on_past'] = True
现在发生的是,如果实例化的dag没有任何错误,我们将看到所需的效果。
然而,假设dag-a计划每小时运行一次。按计划触发dag-a-i1实例的时间。然后dag-a-i1任务t1成功运行,然后t2开始运行并失败。在该场景中,我们看到dag-a-i1实例按预期停止。当下一个小时到来时,我们看到dag-a-i2实例被触发,我们看到该dag实例(i2)的任务t1开始运行,比如说完成,然后dag-a-i2停止,因为其t2无法运行,因为t2的前一个实例(对于dag-a-i1)的状态为失败

我们需要看到的行为是第二个实例没有被触发,或者如果它被触发,我们不希望看到第二个实例的任务t1被触发。这给我们带来了问题


非常感谢您的帮助。

在我开始回答之前,我将设置一个与您在问题中提出的命名约定不同的命名约定

DagA.TimeA.T1
将引用DAG
a
在时间
a
执行任务
T1
的实例

接下来,我看到了两个潜在的解决方案

第一个:

虽然不是特别漂亮,但您可以在DAG的开头添加一个传感器任务。该传感器应等待同一DAG的最终任务执行。类似于以下的方法应该可以工作:

from airflow import DAG
from airflow.operators.dummy_operator import DummyOperator
from airflow.operators.sensors import ExternalTaskSensor
from datetime import timedelta

dag = DAG(dag_id="ETL", schedule_interval="@hourly")
ensure_prior_success = ExternalTaskSensor(external_dag_id="ETL", 
external_task_id="final_task", execution_delta=timedelta(hours=1))
final_task = DummyOperator(task_id="final_task", dag=dag)
以这种方式编写,如果在运行
DagA.TimeA
期间任何非传感器任务失败,
DagA.TimeB
将开始执行其传感器任务,但最终将超时

如果你选择这样写你的DAG,有几件事你应该注意

  • 如果您计划执行此DAG的回填(或者,如果您认为可能的话),您应该将DAG的
    max\u active\u runs
    设置为较低的数值。原因是,足够大的回填可能会用传感器任务填充全局任务队列,并造成新任务无法排队的情况

  • 此DAG的首次运行需要人工干预。人员需要将初始传感器任务标记为成功(因为之前没有运行,传感器无法成功完成)

  • 第二个:

    我不确定您的任务执行的是什么工作,但为了举例,让我们假设它们涉及到对数据库的写入。创建一个操作员,查看您的数据库,寻找
    DagA.TimeA.T3
    成功完成的证据

    正如我所说的,在不知道您的任务是什么的情况下,很难提供关于该操作员的具体建议。如果您的用例涉及恒定数量的数据库写入,那么您可以执行查询来计算目标表
    WHERE TIME中存在的文档数量
    
    from airflow import DAG
    from airflow.operators.dummy_operator import DummyOperator
    from airflow.operators.sensors import ExternalTaskSensor
    from datetime import timedelta
    
    dag = DAG(dag_id="ETL", schedule_interval="@hourly")
    ensure_prior_success = ExternalTaskSensor(external_dag_id="ETL", 
    external_task_id="final_task", execution_delta=timedelta(hours=1))
    final_task = DummyOperator(task_id="final_task", dag=dag)