AIrflow - 跨多个文件拆分DAG定义

时间:2017-01-05 19:55:24

标签: airflow

刚开始使用Airflow并想知道构建大型DAG的最佳实践是什么。对于我们的ETL,我们有许多属于逻辑分组的任务,但这些组依赖于彼此。以下哪项被认为是最佳做法?

  • 包含该文件中所有任务的一个大型DAG文件
  • 在多个文件中拆分DAG定义(如何执行此操作?)
  • 定义多个DAG,每个任务组一个,并使用ExternalTask​​Sensor设置它们之间的依赖关系

也欢迎其他建议。

3 个答案:

答案 0 :(得分:9)

DAG只是python文件。因此,您可以将单个dag定义拆分为多个文件。不同的文件应该只有接受dag对象的方法,并使用该dag对象创建任务。

但请注意,您应该只在全局范围内使用一个dag对象。 Airflow将全局范围内的所有dag对象作为单独的dags进行拾取。

通常认为保持每个dag尽可能简洁是一种好习惯。但是,如果您需要设置此类依赖项,则可以考虑使用子标记。有关此内容的更多信息,请访问:https://airflow.incubator.apache.org/concepts.html?highlight=subdag#scope

您也可以使用ExternalTask​​Sensor,但要注意随着dag数量的增加,处理任务之间的外部依赖关系可能会变得更加困难。我认为子标签可能是你用例的方法。

答案 1 :(得分:1)

随着 TaskGroups 在 Airflow 2.x 中的出现,值得对 a previous answer 进行扩展。 TaskGroups 只是任务的 UI 分组,但它们也用作一堆相关任务的方便的逻辑分组。 TaskGroup 中的任务可以捆绑和抽象出来,以便更容易地从更大的部分构建 DAG。话虽如此,拥有一个充满相关任务的文件可能仍然很有用,而无需将它们捆绑到一个任务组中。

分解 DAG 的技巧是将 DAG 放在一个文件中,例如 my_dag.py,将任务的逻辑块或任务组放在单独的文件中,每个文件有一个逻辑任务块或任务组。每个文件都包含函数(或方法,如果您想采用面向对象的方法),每个函数都返回一个操作员实例或一个 TaskGroup 实例。

为了说明,my_dag.py(如下)从 foo_bar_tasks.py 导入操作符返回函数,并从 xyzzy_taskgroup.py 导入 TaskGroup 返回函数。在 DAG 上下文中,调用这些函数并将它们的返回值分配给任务或任务组变量,这些变量可以分配上游/下游依赖项。

dags/my_dag.py

# std lib imports
 
from airflow import DAG
# other airflow imports
 
from includes.foo_bar_tasks import build_foo_task, build_bar_task
from includes.xyzzy_taskgroup import build_xyzzy_taskgroup
 
with DAG(dag_id="my_dag", ...) as dag:
 
    # logical chunk of tasks
    foo_task = build_foo_task(dag=dag, ...)
    bar_task = build_bar_task(dag=dag, ...)
 
    # taskgroup
    xyzzy_taskgroup = build_xyzzy_taskgroup(dag=dag, ...)
 
    foo_task >> bar_task >> xyzzy_taskgroup

plugins/includes/foo_bar_tasks.py

# std lib imports
 
from airflow import DAG
from airflow.operators.foo import FooOperator
from airflow.operators.bar import BarOperator
# other airflow imports
 
def build_foo_task(dag: DAG, ...) -> FooOperator:
    # ... logic here ...
    foo_task = FooOperator(..., dag=dag)
 
    return foo_task
 
def build_bar_task(dag: DAG, ...) -> BarOperator:
    # ... logic here ...
    bar_task = BarOperator(..., dag=dag)
 
    return bar_task

plugins/includes/xyzzy_taskgroup.py

# std lib imports
 
from airflow import DAG
from airflow.operators.baz import BazOperator
from airflow.operators.qux import QuxOperator
from airflow.utils import TaskGroup
# other airflow imports
 
def build_xyzzy_taskgroup(dag: DAG, ...) -> TaskGroup:
    xyzzy_taskgroup = TaskGroup(group_id="xyzzy_taskgroup")
 
    # ... logic here ...
    baz_task = BazOperator(task_id="baz_task", task_group=xyzzy_taskgroup, ...)
 
    # ... logic here ...
    qux_task = QuxOperator(task_id="qux_task", task_group=xyzzy_taskgroup, ...)
 
    baz_task >> qux_task
 
    return xyzzy_taskgroup

答案 2 :(得分:0)

似乎可以将您的 Python 模块放入 plugins/ 子文件夹并从 DAG 文件中导入它们:

https://airflow.apache.org/docs/apache-airflow/stable/plugins.html