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

时间:2017-10-02 17:05:10

标签: airflow apache-airflow airflow-scheduler

我们的气流实施中有多个运营商的笨蛋。 假设dag-a具有运算符t1,t2,t3,它们被设置为顺序运行(即t2取决于t1,t3取决于t2。)

 task_2.set_upstream(task_1)
 task_3.set_upstream(task_2)

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

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

da['depends_on_past'] = True

现在正在发生的事情是,如果实例化的dag没有任何错误,我们会看到所需的效果。
但是,让我们说dag-a计划每小时运行一次。在小时dag-a-i1实例按计划触发。然后dag-a-i1任务t1成功运行,然后t2开始运行并失败。在那种情况下,我们看到dag-a-i1实例按预期停止。当下一个小时到来时,我们看到dag-a-i2实例被触发,我们看到该dag实例的任务t1(i2)开始运行并让我们说完成,然后dag-a-i2停止,因为它的t2不能因为t2的前一个实例(对于dag-a-i1)状态失败。

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

感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

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

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

继续,我在这里看到两个可能的解决方案。

第一个:

虽然不是特别漂亮,但您可以在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,您应该注意一些事项。

  1. 如果您计划执行此DAG的回填(或者,如果您认为有可能),则应将DAG的max_active_runs设置为较低的数字。原因是足够大的回填可以用传感器任务填充全局任务队列,并创建新任务无法排队的情况。

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

  3. 第二个:

    我不确定您的任务正在执行什么工作,但为了举例,我们说它们涉及对数据库的写入。创建一个运算符,查看数据库中DagA.TimeA.T3成功完成的证据。

    正如我所说,在不知道你的任务在做什么的情况下,很难就这个运营商的样子提供具体的建议。如果您的用例涉及恒定数量的数据库写入,则可以执行查询以计算目标表WHERE TIME <= NOW - 1 HOUR中存在的文档数。