Як запустити завдання Airflow лише тоді, коли новий розділ / дані, які можна змінити в таблиці AWS athena, використовуючи DAG в python?


9

У мене є сценарій, як показано нижче:

  1. Запустити a Task 1і Task 2лише тоді, коли нові дані для них доступні у вихідній таблиці (Athena). Тригер для Task1 і Task2 повинен відбуватися при новому розділі даних через день.
  2. Тригер Task 3тільки після завершення Task 1таTask 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 reisen

@ Bernardostearnsreisen, Іноді Task1і Task2йде в циклі. Для мене дані завантажуються у вихідну таблицю Афіни 10:00 CET.
панкай

Ви маєте на увазі цикл ви маєте на увазі, потік повітря повторює Task1 та Task2 багато разів, поки це не вдасться?
Bernardo stearns reisen

@Bernardostearnsreisen, так точно
pankaj

1
@Bernardostearnsreisen, я не знав, як нагородити нагороду :)
pankaj

Відповіді:


1

Я вважаю, що ваше питання вирішує дві основні проблеми:

  1. забувши налаштувати schedule_intervalчітко, щоб @daily налаштовував те, чого ви не очікуєте.
  2. Як запустити та повторити спробу виконання дага, коли ви залежите від зовнішньої події для завершення виконання

коротка відповідь: встановіть чітко свій графік_інтервалу за допомогою формату завдання cron і використовуйте оператори датчиків, щоб час від часу перевіряти

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ви перевірите, чи відбулася подія.

Як чітко вирішувати завдання на cron, коли ви встановлюєте свій так,@dailyяк ви робили:

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). Тож він намагається запустити даг опівночі, він не вдається. знову через 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 усіх днів_ місяця всіх місяців усіх днів усіх днів

Таким чином, ваш випадок запускається так щохвилини: 0 хвилин 10 годин усіх днів_офіційного місяця всіх_місяців усіх днів_виходу. Це перекладається у форматі завдання cron на:

0 10 * * *

Як запустити та повторити спробу виконання дага, коли ви залежите від зовнішньої події для завершення виконання

  1. ви можете викликати даг повітряного потоку від зовнішньої події за допомогою команди airflow trigger_dag. це можливо, якби деякі, як ви могли запустити лямбда-функцію / скрипт python для націлювання на ваш екземпляр повітряного потоку.

  2. Якщо ви не можете запустити даг зовнішньо, то використовуйте оператор датчика, як це робив OP, встановіть йому poke_time і встановіть достатньо велику кількість повторень.


Дякую за це Крім того, якщо я хочу запустити завдання на основі події, а не часу, тобто, як тільки новий розділ даних стане доступним у джерелі "AWS Athena Tables", наступне завдання має спрацювати. Тоді як скласти графік. Чи достатньо мій поточний код
панкай

@pankaj, я бачу лише дві альтернативи. Я мало знаю про Aws Atena, але ви можете викликати даг повітряного потоку від зовнішньої події за допомогою команди airflow trigger_dag. це можливо, якби деякі, як ви могли запустити лямбда-функцію / скрипт python для націлювання на ваш екземпляр повітряного потоку.
Бернардо stearns відроджений

інша альтернатива - це більш-менш те, що ви робите, оскільки у вас немає тригера на основі подій, вам потрібно періодично перевіряти, чи відбулася ця подія. Таким чином, використовуючи це поточне рішення, було б встановлено роботу з крон протягом ряду годин, запускаючи даг з високою частотою хвилин ... багато не вдасться, але це зможе досить швидко зловити після події
Бернардо stearns reisen

@ Bernado, я розібрав пакет у Airflow, який називається AwsGlueCatalogPartitionSensorразом із командою airflow {{ds_nodash}}для виходу з розділу. Тоді моє запитання, як це запланувати.
панкай

@Benado, Чи можете ви подивитись на мій код, де я реалізував вищезгаданий чек, і дайте свої вкладення
pankaj
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.