仅当使用Python中的DAG在AWS athena表中可用的新分区/数据可用时,如何触发Airflow任务?


9

我有一个如下的场景:

  1. 仅在源表(Athena)中有新数据可用时才触发Task 1Task 2。一天中进行新的数据分区时,应该触发Task1和Task2。
  2. 触发Task 3仅完成Task 1Task 2
  3. Task 4仅触发完成Task 3

在此处输入图片说明

我的密码

from airflow import DAG

from airflow.contrib.sensors.aws_glue_catalog_partition_sensor import AwsGlueCatalogPartitionSensor
from datetime import datetime, timedelta

from airflow.operators.postgres_operator import PostgresOperator
from utils import FAILURE_EMAILS

yesterday = datetime.combine(datetime.today() - timedelta(1), datetime.min.time())

default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': yesterday,
    'email': FAILURE_EMAILS,
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 1,
    'retry_delay': timedelta(minutes=5)
}

dag = DAG('Trigger_Job', default_args=default_args, schedule_interval='@daily')

Athena_Trigger_for_Task1 = AwsGlueCatalogPartitionSensor(
    task_id='athena_wait_for_Task1_partition_exists',
    database_name='DB',
    table_name='Table1',
    expression='load_date={{ ds_nodash }}',
    timeout=60,
    dag=dag)

Athena_Trigger_for_Task2 = AwsGlueCatalogPartitionSensor(
    task_id='athena_wait_for_Task2_partition_exists',
    database_name='DB',
    table_name='Table2',
    expression='load_date={{ ds_nodash }}',
    timeout=60,
    dag=dag)

execute_Task1 = PostgresOperator(
    task_id='Task1',
    postgres_conn_id='REDSHIFT_CONN',
    sql="/sql/flow/Task1.sql",
    params={'limit': '50'},
    trigger_rule='all_success',
    dag=dag
)

execute_Task2 = PostgresOperator(
    task_id='Task2',
    postgres_conn_id='REDSHIFT_CONN',
    sql="/sql/flow/Task2.sql",
    params={'limit': '50'},
    trigger_rule='all_success',
    dag=dag
)



execute_Task3 = PostgresOperator(
    task_id='Task3',
    postgres_conn_id='REDSHIFT_CONN',
    sql="/sql/flow/Task3.sql",
    params={'limit': '50'},
    trigger_rule='all_success',
    dag=dag
)

execute_Task4 = PostgresOperator(
    task_id='Task4',
    postgres_conn_id='REDSHIFT_CONN',
    sql="/sql/flow/Task4",
    params={'limit': '50'},
    dag=dag
)



execute_Task1.set_upstream(Athena_Trigger_for_Task1)
execute_Task2.set_upstream(Athena_Trigger_for_Task2)

execute_Task3.set_upstream(execute_Task1)
execute_Task3.set_upstream(execute_Task2)

execute_Task4.set_upstream(execute_Task3)

实现它的最佳最佳方法是什么?


您对此解决方案有任何疑问吗?
Bernardo stearns

@Bernardostearnsreisen,有时Task1Task2会循环播放。对我来说,数据是在上午10点CET加载到Athena源表中的。
pankaj

循环循环,气流重试Task1和Task2多次直到成功为止?
Bernardo stearns

@Bernardostearnsreisen,是的
pankaj

1
@Bernardostearnsreisen,我不知道如何授予赏金:)
pankaj

Answers:


1

我相信您的问题解决了两个主要问题:

  1. 忘记以schedule_interval显式方式配置,因此@daily正在设置您不期望的内容。
  2. 当您依赖外部事件来完成执行时,如何触发并重试dag的执行

简短的答案:使用cron作业格式显式设置您的schedule_interval,并使用传感器运算符不时检查

default_args={
        'retries': (endtime - starttime)*60/poke_time
}
dag = DAG('Trigger_Job', default_args=default_args, schedule_interval='0 10 * * *')
Athena_Trigger_for_Task1 = AwsGlueCatalogPartitionSensor(
     ....
    poke_time= 60*5 #<---- set a poke_time in seconds
    dag=dag)

这里startime是什么时候你的日常任务将启动,endtime什么是一天中的最后一次,你应该检查,如果事件被标记为失败和以前做poke_time是你的时间间隔sensor_operator将检查所发生的事件。

每当您将dag设置为@daily像您一样时,如何显式解决cron作业

dag = DAG('Trigger_Job', default_args=default_args, schedule_interval='@daily')

文档中,您可以看到您实际上正在做: @daily - Run once a day at midnight

现在可以理解为什么会出现超时错误,并在5分钟后失败,因为您设置了'retries': 1'retry_delay': timedelta(minutes=5)。因此,它尝试在午夜运行dag,但失败了。5分钟后重试,然后再次失败,因此将其标记为失败。

所以基本上@daily run设置一个隐式的cron作业:

@daily -> Run once a day at midnight -> 0 0 * * *

cron作业格式为以下格式,您可以将值设置为*每当要说“全部”时。

Minute Hour Day_of_Month Month Day_of_Week

因此,@ daily基本上是说每隔一周运行一次:分钟0小时0 of all days_of_month of all days_of_week的所有月份

因此,您的案例每隔以下时间运行一次:所有days_of_week的all_months的所有days_of_month的分钟0小时10。这将以cron作业格式转换为:

0 10 * * *

当您依赖外部事件来完成执行时,如何触发并重试dag的执行

  1. 您可以使用以下命令在外部事件中触发气流中断airflow trigger_dag。如果您可以通过某种方式触发lambda函数/ python脚本来针对您的气流实例,那么这将是可能的。

  2. 如果您不能从外部触发dag,则使用像OP一样的传感器运算符,将其设置为poke_time并设置合理的重试次数。


谢谢你 另外,如果我要基于事件而不是时间来触发任务,即一旦源“ AWS Athena Tables”中的新数据分区可用时,下一个任务就应该触发。那我该如何安排。我当前的代码是否足够恰当。
pankaj

@pankaj,我只看到两种选择。我对aws athena不太了解,但是您可以使用command触发外部事件引起的气流中断airflow trigger_dag。如果您可以通过某种方式触发lambda函数/ python脚本来针对您的气流实例,那么这将是可能的。
Bernardo stearns

另一个选择或多或少是您正在做什么,因为您没有基于事件的触发器,因此需要定期检查此事件是否发生。因此,使用此当前解决方案将在一段时间内频繁地执行一次cron作业,几分钟内就会大量运行……很多会失败,但在事件发生后它能够很快赶上来
Bernardo stearns reisen

@Bernado,我已经弄清楚了Airflow中的软件包AwsGlueCatalogPartitionSensor以及{{ds_nodash}}用于分区出口的airflow 命令。我的问题是如何安排这个。
pankaj

@Benado,你可以看看我的代码,我所提到的检查落实,并给你的投入
潘卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.