气流,标记任务成功或在运行dag之前跳过它

时间:2018-06-19 17:49:29

标签: python airflow google-cloud-composer

我们有一个庞大的DAG,其中包含许多小型和快速任务,以及一些大型和耗时的任务。

我们只想运行DAG的一部分,而找到的最简单的方法是不添加我们不想运行的任务。问题在于我们的DAG具有许多相互依赖关系,因此当我们要跳过某些任务时,要不中断工作就成为了一个真正的挑战。

是否可以通过默认方式为任务添加状态? (对于每次运行),如下所示:

# get the skip list from a env variable    
task_list = models.Variable.get('list_of_tasks_to_skip')

dag.skip(task_list)

for task in task_list:
    task.status = 'success'

2 个答案:

答案 0 :(得分:2)

如注释中所述,应使用BranchPythonOperator(或ShortCircuitOperator)来防止执行耗时的任务。如果您需要运行这些耗时任务的下游操作员,可以使用TriggerRule.ALL_DONE来使这些操作员运行,但是请注意,即使上游操作员失败,此操作也将运行。

您可以使用气流变量来影响这些BranchPythonOperators,而不必更新DAG,例如:

from airflow.models import Variable

def branch_python_operator_callable()
  return Variable.get('time_consuming_operator_var')

并使用branch_python_operator_callable作为BranchPythonOperator的可调用Python。

答案 1 :(得分:0)

您是否考虑过在可调用对象周围使用装饰器/高阶函数?

我正在考虑使用以下内容:

def conf_task_id_skip(python_callable):
    def skip_if_configured(*args, **context):
        task_id = context["task_id"]
        dag_run = context["dag_run"]
        skip_task_ids = dag_run.conf.get("skip_task_ids", [])

        if skip_task_ids and task_id in skip_task_ids:
            return None
        else:
            return python_callable(*args, **context)
    
    return skip_if_configured
PythonOperator(
    task_id="task_id", 
    python_callable=conf_task_id_skip(task_callable)
)

然后,如果我愿意,我可以手动传递我想跳过的任务(并且仍然成功)。

如果您愿意,您还可以通过添加检查是否禁止跳过(例如在 prod 中)来提高稳健性:

def conf_task_id_skip(python_callable):
    def skip_if_configured(*args, **context):
        if Variable.get("disallow_conf_task_id_skip"):
            return python_callable(*args, **context)

        task_id = context["task_id"]
        dag_run = context["dag_run"]
        skip_task_ids = dag_run.conf.get("skip_task_ids", [])

        if skip_task_ids and task_id in skip_task_ids:
            return None
        else:
            return python_callable(*args, **context)
    
    return skip_if_configured