将顶级DAG连接在一起

时间:2018-07-13 12:50:27

标签: airflow

我需要有几个相同的(仅在参数上有所不同)顶级DAG ,这些也可以与以下约束/假设一起触发:

  • 单个顶级DAG将具有schedule_interval=None,因为它们仅偶尔需要手动触发
  • 但是,DAG系列需要每天运行
  • 串联的DAG的
  • Order number 是固定的(在编写代码之前已知),并且很少更改(几个月内一次)
  • 无论DAG是失败还是成功,触发链都不得中断
  • 当前它们必须串联运行;将来可能需要并行触发

因此,我在dags目录中为每个DAG创建了一个文件,现在我必须连接它们以顺序执行。我确定了两种方法可以做到:

  1. SubDagOperator

  2. TriggerDagRunOperator

    • 可以在my demo中运行,但是可以以 parallel (不是顺序)运行,因为它不等待触发的DAG 完成在转到下一个之前
    • ExternalTaskSensor可能有助于克服上述限制,但会使事情变得混乱

我的问题是

  • 如何克服parent_id的{​​{1}}中dag_id前缀的限制?
  • 如何强制SubDag强制等待DAG完成
  • 是否有任何其他/更好的方法可以将独立的(顶级)DAG捆绑在一起?
  • 我为每个顶级DAG 创建单独的文件(对于仅在输入方面有所不同的DAG)是否有解决方法?

我将puckel/docker-airflow

一起使用
  • TriggerDagRunOperator
  • Airflow 1.9.0-4
  • Python 3.6-slimCeleryExecutor

EDIT-1

澄清 @Viraj Parekh queries

  

您能否详细说明等待完成的含义   触发之前DAG的功能?

当我触发redis:3.2.7 DAG时,应该依次使用import_parent_v1触发的所有3个外部DAG都开始并行运行。实际上, logs 表示,虽然它们被一个接一个地触发,但执行在下一个DAG(TriggerDagRunOperator)之前完成。 enter image description here enter image description here 注意:在此示例中,顶级DAG被命名为TriggerDagRunOperator,而它们对应的importer_child_v1_db_X(对于task_id)被命名为TriggerDagRunOperator

  

是否可以仅将TriggerDagRunOperator用作   DAG中的最后一项任务?

我必须在工作流中将几个相似的(仅在参数上有所不同)DAG链接在一起,以一个一个的触发它们。因此,我最后不能只给出一个 importer_v1_db_X,有很多(这里是3个,但在生产中最多可以有15个)

4 个答案:

答案 0 :(得分:3)

@Viraj Parekh answer的提示下,我能够按预期的方式使TriggerDagRunOperator工作。我特此发布我的(部分)答案;会在情况变得清晰时更新。


  

如何克服parent_id的{​​{1}}中dag_id前缀的限制?

正如@Viraj所说,没有直接的方法可以实现这一目标。扩展SubDag以删除this check可能有效,但我决定避免使用它


  

如何强制SubDagOperator强制等待DAG完成

  • 看看implementation,很明显TriggerDagRunOperator的工作只是触发触发外部DAG;就是这样。默认情况下,它不是应该等待DAG完成。因此,我观察到的行为是可以理解的。

  • TriggerDagRunOperator是显而易见的出路。但是,在学习ExternalTaskSensor的基础知识时,我依靠的是DAG(Airflow)的手动触发。在这种情况下,schedule_interval=None很难为外部任务(正在等待其完成的任务)准确地指定ExternalTaskSensor,从而使sensor gets stuck失败。

  • 因此,从implementation那里获得提示,我等待{em}的所有execution_date 的完成,从而使ExternalTaskSensor的行为minor adjustment有关任务

    task_instance

    这达到了desired result:外部DAG依次运行。


  

创建单独文件的方法是否有解决方法?   (对于仅在输入上有所不同的DAG)每个顶级DAG?

再次通过@Viraj,可以通过assigning DAGs to global scope使用execution_date[external_task] >= execution_date[TriggerDagRunOperator] + execution_delta来完成


EDIT-1

也许我是指错误的资源(上面的link已经失效),但是ExternalTaskSensor已经包含参数globals()[dag_id] = DAG(..)execution_delta来轻松限制{{1 }}(s)感测到的任务。

答案 1 :(得分:1)

  • 您能否通过触发DAG等待完成DAG来进一步说明您的意思?是否可以仅将TriggerDagRunOperator成为DAG中的最后一项任务?

  • 要创建与DAG类似的DAG,可以从一个Python文件动态生成DAG。您可以这样做:

从气流导入DAG

from airflow.operators.python_operator import PythonOperator


def create_dag(dag_id,
               schedule,
               dag_number,
               default_args):

def hello_world_py(*args):
    print('Hello World')
    print('This is DAG: {}'.format(str(dag_number)))

dag = DAG(dag_id,
          schedule_interval=schedule,
          default_args=default_args)

with dag:
    t1 = PythonOperator(
        task_id='hello_world',
        python_callable=hello_world_py,
        dag_number=dag_number)

return dag


# build a dag for each number in range(10)
for n in range(1, 10):
dag_id = 'hello_world_{}'.format(str(n))

default_args = {'owner': 'airflow',
                'start_date': datetime(2018, 1, 1)
                }

schedule = '@daily'

dag_number = n

globals()[dag_id] = create_dag(dag_id,
                              schedule,
                              dag_number,
                              default_args)

您可以在此处详细了解该方法。如果你们大多数人都在生产DAG,它们很相似,那么您可能要考虑将配置存储在气流变量enter link description here

您可能无法克服SubDag Operator的前缀限制-我建议您从工作流程中完全删除SubDag,而仅将它们作为独立的DAG运行-这样可以更轻松地返回和如果您发现自己必须这样做,请重新运行较旧的DagRun。

答案 2 :(得分:1)

当我使用 schedule none 时,这对我有用。


trigger_dag = TriggerDagRunOperator(
    task_id=f'dag_id-trigger',
    trigger_dag_id='dag_id',
    python_callable=set_args,
    dag=dag,
)


def get_most_recent_dag_run(execution_date, **kwargs):
    return DagRun.find(dag_id='dag_id').pop().execution_date


sensor = ExternalTaskSensor(
    task_id=f'dag_id-sensor',
    external_dag_id='dag_id',
    execution_date_fn=get_most_recent_dag_run,
    dag=dag,
    poke_interval=5,
    external_task_id='last_task_id' # This is task need to be in your external dag
)

答案 3 :(得分:1)

如果您正在寻找一种等待触发 DAG 完成的方法,那么在 Airflow 2.0 中它变得比以前容易多了。
有一个新版本的 TriggerDagRunOperator 允许您这样做。不再需要使用 ExternalTask​​Sensor。
我制作了一个 10 分钟的教程https://youtu.be/8uKW0mPWmCk

享受