파이썬에서 DAG를 사용하여 AWS athena 테이블에서 새 파티션 / 데이터를 사용할 수있는 경우에만 에어 플로우 작업을 트리거하는 방법은 무엇입니까?


9

나는 아래와 같은 scenerio를 가지고있다 :

  1. 트리거 Task 1Task 2때만 새로운 데이터 소스 테이블 (아테나)에서 그들을 위해에 avialable이다. 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는

Bernardostearnsreisen @, 때로는 Task1Task2루프에 간다. 나를 위해 데이터는 Athena 소스 테이블 10 AM CET에로드됩니다.
pankaj

루프가 계속되면 공기 흐름이 성공할 때까지 Task1과 Task2를 여러 번 재 시도합니까?
Bernardo는

@Bernardostearnsreisen, 넵 정확히
판 카즈

1
@Bernardostearnsreisen, 나는 현상금을 수여하는 방법을 몰랐습니다 :)
pankaj

답변:


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')

로부터 문서 , 당신은 당신이 actualy 일을 할 수 있습니다 볼 수 있습니다 : @daily - Run once a day at midnight

이제 시간 초과 오류가 발생하는 이유를 이해하고 및를 설정 'retries': 1하여 5 분 후에 실패합니다 'retry_delay': timedelta(minutes=5). 그래서 자정에 dag를 실행하려고 시도하면 실패합니다. 5 분 후에 다시 시도하고 다시 실패하므로 실패로 플래그가 지정됩니다.

따라서 기본적으로 @daily run은 다음과 같은 암시 적 cron 작업을 설정합니다.

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

크론 작업 형식은 아래 형식이며 *"모두"라고 할 때마다 값을 설정합니다 .

Minute Hour Day_of_Month Month Day_of_Week

@daily는 기본적으로 이것을 매일 실행한다고 말합니다 : 모든 요일의 0 분 0 분 모든 요일의 0 개월 0

따라서 귀하의 사례는 모든 요일마다 0 분 10 분 _ 모든 요일 _ 모든 요일 _ 주 _ 오일마다 실행됩니다. 이것은 cron 작업 형식으로 다음과 같이 변환됩니다.

0 10 * * *

실행을 완료하기 위해 외부 이벤트에 의존 할 때 dag 실행을 올바르게 트리거하고 재 시도하는 방법

  1. 명령을 사용하여 외부 이벤트에서 공기 흐름을 막을 수 있습니다 airflow trigger_dag. airflow 인스턴스를 대상으로 람다 함수 / 파이썬 스크립트를 트리거하는 방법이 있다면 가능할 것입니다.

  2. 외부 적으로 데이터를 트리거 할 수없는 경우 OP처럼 센서 연산자를 사용하고 poke_time을 설정하고 합리적인 재시도 횟수를 설정하십시오.


고마워 또한 시간이 아닌 이벤트를 기준으로 작업을 트리거하려는 경우 즉, 소스`AWS Athena Tables '에서 새 데이터 파티션을 즉시 사용할 수있게되면 다음 작업이 트리거되어야합니다. 그런 다음 어떻게 예약합니까? 현재 코드가 충분합니까?
pankaj

@ pankaj, 나는 두 가지 대안 만 봅니다. 나는 aws athena에 대해 많이 알지 못하지만 명령을 사용하여 외부 이벤트에서 공기 흐름을 막을 수 있습니다 airflow trigger_dag. airflow 인스턴스를 대상으로 람다 함수 / 파이썬 스크립트를 트리거하는 방법이 있다면 가능할 것입니다.
Bernardo

이벤트 기반 트리거가 없기 때문에이 이벤트가 발생했는지 주기적으로 확인해야하므로 다른 대안은 현재 수행중인 작업입니다. 이 현재의 솔루션을 사용하여이 시간 범위 cron 작업을 설정됩니다 그래서 분의 높은 주파수에서 DAG를 실행 ... 많은 사람들이 실패하지만 사건 발생 후 상당히 빨리 잡을 수있을 것입니다
베르나르도 스턴 레이센

@ Bernado, 파티션 출구에 대한 AwsGlueCatalogPartitionSensor공기 흐름 명령과 함께 공기 흐름 에서 패키지를 알아 냈습니다 {{ds_nodash}}. 내 질문은 다음 일정을 설정하는 방법입니다.
pankaj

@Benado, 위에서 언급 한 확인을 구현 한 코드를 살펴보고 입력 사항을 제공 할 수 있습니까
pankaj
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.