Airflow 在Apache中实现跨DAG依赖

Airflow 在Apache中实现跨DAG依赖,airflow,directed-acyclic-graphs,Airflow,Directed Acyclic Graphs,我正在尝试实现两个DAG之间的DAG依赖关系,例如A和B。DAG A每小时运行一次,DAG B每15分钟运行一次 每次DAG B开始运行时,我要确保DAG A未处于运行状态 如果发现DAG A正在运行,则DAG B必须等待DAG A完成运行 如果DAG A未运行,DAG B可以继续执行其任务 DAG A: from datetime import datetime,timedelta from airflow import DAG from airflow.operators.dummy_ope

我正在尝试实现两个DAG之间的DAG依赖关系,例如A和B。DAG A每小时运行一次,DAG B每15分钟运行一次

  • 每次DAG B开始运行时,我要确保DAG A未处于运行状态
  • 如果发现DAG A正在运行,则DAG B必须等待DAG A完成运行
  • 如果DAG A未运行,DAG B可以继续执行其任务
  • DAG A:

    from datetime import datetime,timedelta
    from airflow import DAG
    from airflow.operators.dummy_operator import DummyOperator
    
    default_args = {
        'owner': 'dependency',
        'depends_on_past': False,
        'start_date': datetime(2020, 9, 10, 10, 1),
        'email': ['xxxx.com'],
        'email_on_failure': True,
        'email_on_retry': False,
        'retries': 1,
        'retry_delay': timedelta(minutes=5)
    }
    
    with DAG('DAG_A', schedule_interval='0/60 * * * *',max_active_runs=1, catchup=False,
             default_args=default_args) as dag:
    
        task1 = DummyOperator(task_id='task1', retries=1, dag=dag)
        task2 = DummyOperator(task_id='task2', retries=1, dag=dag)
        task3 = DummyOperator(task_id='task3', retries=1, dag=dag)
    
        task1 >> task2 >> task3
    
    DAG B:

    from datetime import datetime,timedelta
    from airflow import DAG
    from airflow.operators.dummy_operator import DummyOperator
    
    default_args = {
        'owner': 'dependency',
        'depends_on_past': False,
        'start_date': datetime(2020, 9, 10, 10, 1),
        'email': ['xxxx.com'],
        'email_on_failure': True,
        'email_on_retry': False,
        'retries': 1,
        'retry_delay': timedelta(minutes=5)
    }
    
    with DAG('DAG_B', schedule_interval='0/15 * * * *',max_active_runs=1, catchup=False,
            default_args=default_args) as dag:
    
        task4 = DummyOperator(task_id='task4', retries=1, dag=dag)
        task5 = DummyOperator(task_id='task5', retries=1, dag=dag)
        task6 = DummyOperator(task_id='task6', retries=1, dag=dag)
    
        task4 >> task5 >> task6
    
    我已尝试使用ExternalTaskSensor操作符。我无法理解传感器是否发现DAG A处于成功状态,它将触发下一个任务,否则请等待任务完成


    提前感谢。

    我认为,以“一般”方式实现这一点的唯一方法是使用一些外部锁定机制

    通过使用池,您可以获得相当好的近似值:

    如果将池大小设置为1,并将dag A和B都指定给池,则一次只能运行其中一个。你也可以以你认为最好的方式增加优先级权重,以防你需要优先考虑A而不是B,或者反过来。

    你可以用它来实现你想要的。关键方面是使用正确的
    执行日期
    初始化此传感器,即在您的示例中,DAG\u A的最后一次
    DagRun
    执行日期
    。 检查此示例,其中DAG_A每9分钟运行一次,持续200秒DAG_B每3分钟跑步一次,持续30秒。这些值是任意的,仅用于演示目的,几乎可以是任何值

    DAG A(这里没有什么新内容):

    导入时间
    从气流导入DAG
    从airflow.models.baseoperator导入链
    从airflow.operators.dummy导入DummyOperator
    从afflow.operators.python导入PythonOperator
    从airflow.utils.dates导入天\u
    def_正在执行任务(**kwargs):
    打印(“启动任务”)
    时间。睡眠(200)
    打印(“已完成的任务”)
    dag=dag(
    dag\u id=“示例\u外部任务\u传感器\u a”,
    默认参数={“所有者”:“气流”},
    开始日期=日前(1),
    附表_interval=“*/9****”,
    tags=['example_dags'],
    catchup=False
    )
    对于dag:
    start=DUMMY操作器(
    任务(id='start')
    task_a=蟒蛇操作员(
    task_id='task_a',
    python\u callable=\u正在执行任务,
    )
    链(开始,任务a)
    
    DAG B:

    from datetime import datetime,timedelta
    from airflow import DAG
    from airflow.operators.dummy_operator import DummyOperator
    
    default_args = {
        'owner': 'dependency',
        'depends_on_past': False,
        'start_date': datetime(2020, 9, 10, 10, 1),
        'email': ['xxxx.com'],
        'email_on_failure': True,
        'email_on_retry': False,
        'retries': 1,
        'retry_delay': timedelta(minutes=5)
    }
    
    with DAG('DAG_B', schedule_interval='0/15 * * * *',max_active_runs=1, catchup=False,
            default_args=default_args) as dag:
    
        task4 = DummyOperator(task_id='task4', retries=1, dag=dag)
        task5 = DummyOperator(task_id='task5', retries=1, dag=dag)
        task6 = DummyOperator(task_id='task6', retries=1, dag=dag)
    
        task4 >> task5 >> task6
    
    导入时间
    从气流导入DAG
    从airflow.utils.db导入提供\u会话
    从afflow.models.dag导入获取上次运行
    从airflow.models.baseoperator导入链
    从airflow.operators.dummy导入DummyOperator
    从afflow.operators.python导入PythonOperator
    从airflow.utils.dates导入天\u
    从airflow.sensors.external_任务导入ExternalTaskSensor
    def_正在执行_任务():
    时间。睡眠(30)
    打印(“已完成的任务”)
    @提供会话
    定义获取执行日期(执行日期,会话=无,**kwargs):
    dag_a_last_run=获取最后一次运行(
    “示例\u外部任务\u传感器\u a”,会话)
    打印(最后一次运行)
    打印(f“执行日期:{dag_a_last_run.execution_DATE}”)
    返回上次运行日期。执行日期
    dag=dag(
    dag_id=“示例\u外部任务\u传感器”,
    默认参数={“所有者”:“气流”},
    开始日期=日前(1),
    附表_interval=“*/3****”,
    tags=['example_dags'],
    catchup=False
    )
    对于dag:
    start=DUMMY操作器(
    任务(id='start')
    等待\u dag\u a=外部任务传感器(
    task_id='wait_for_dag_a',
    外部_dag_id='example_external_task_sensor_a',
    允许的状态=[“成功”,“失败”],
    执行日期=获得执行日期,
    脉冲间隔=30
    )
    task_b=蟒蛇算子(
    task_id='task_b',
    python\u callable=\u正在执行任务,
    )
    链(开始、等待任务a、任务b)
    
    我们正在使用
    ExternalTaskSensor
    的参数
    execution\u fn
    ,以获取DAG\u A最后一次DAG运行的
    执行日期
    ,如果我们不这样做,它将等待DAG\u A,执行日期与DAG\u B的实际运行日期相同,在许多情况下可能不存在

    函数
    \u get\u execution\u date\u of_dag\u a
    通过使用气流模型中的
    get\u last\u dagrun
    查询元数据数据库以获取执行日期

    最后,另一个重要参数是
    allowed_states=['success','failed']
    ,我们告诉它等待,直到在其中一个状态中找到DAG_A(即,如果它处于
    运行状态
    将继续执行)

    试试看,让我知道它是否适合你