Làm cách nào để kích hoạt tác vụ Airflow chỉ khi phân vùng / dữ liệu mới có sẵn trong bảng athena AWS sử dụng DAG trong python?


9

Tôi có một scenerio như dưới đây:

  1. Kích hoạt a Task 1Task 2chỉ khi dữ liệu mới có sẵn cho chúng trong bảng nguồn (Athena). Kích hoạt cho Task1 và Task2 sẽ xảy ra khi một liên kết dữ liệu mới trong một ngày.
  2. Task 3Chỉ kích hoạt khi hoàn thành Task 1Task 2
  3. Task 4Chỉ kích hoạt hoàn thànhTask 3

nhập mô tả hình ảnh ở đây

Mã của tôi

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)

Cách tối ưu tốt nhất để đạt được nó là gì?


bạn có bất kỳ vấn đề với giải pháp này?
Bernardo bắt đầu hồi sinh

@ Bernardostearnsreisen, Đôi khi Task1Task2đi theo vòng lặp. Đối với tôi dữ liệu được tải trong bảng nguồn Athena 10 AM CET.
pankaj

ý bạn là cứ lặp đi lặp lại, luồng không khí thử lại Task1 và Task2 nhiều lần cho đến khi nó thành công?
Bernardo bắt đầu hồi sinh

@Bernardostearnsreisen, yup chính xác
pankaj

1
@Bernardostearnsreisen, tôi không biết cách thưởng tiền thưởng :)
pankaj

Câu trả lời:


1

Tôi tin rằng câu hỏi của bạn giải quyết hai vấn đề chính:

  1. quên cấu hình schedule_intervalmột cách rõ ràng để @daily đang thiết lập một cái gì đó bạn không mong đợi.
  2. Cách kích hoạt và thử lại đúng cách thực hiện dag khi bạn phụ thuộc vào một sự kiện bên ngoài để hoàn thành việc thực hiện

câu trả lời ngắn: đặt rõ ràng lịch trình_interval của bạn với định dạng công việc định kỳ và sử dụng toán tử cảm biến để kiểm tra theo thời gian

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)

nơi startimelà mấy giờ nhiệm vụ hàng ngày của bạn sẽ bắt đầu, endtimelần cuối cùng trong ngày bạn nên kiểm tra nếu một sự kiện đã được thực hiện trước khi suy giảm như thất bại và là những gì poke_timelà khoảng thời gian của bạn sensor_operatorsẽ kiểm tra nếu sự kiện đã xảy ra.

Làm thế nào để giải quyết công việc định kỳ một cách rõ ràng bất cứ khi nào bạn đặt dag của bạn@dailygiống như bạn đã làm:

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

từ các tài liệu , bạn có thể thấy bạn đang thực sự làm: @daily - Run once a day at midnight

Điều này có nghĩa là tại sao bạn gặp lỗi hết thời gian và thất bại sau 5 phút vì bạn đã đặt 'retries': 1'retry_delay': timedelta(minutes=5). Vì vậy, nó cố gắng chạy dag vào nửa đêm, nó thất bại. thử lại 5 phút sau và thất bại lần nữa, vì vậy nó đánh dấu là thất bại.

Vì vậy, về cơ bản @daily chạy đang thiết lập một công việc định kỳ ngầm của:

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

Định dạng công việc định kỳ có định dạng bên dưới và bạn đặt giá trị thành *bất cứ khi nào bạn muốn nói "tất cả".

Minute Hour Day_of_Month Month Day_of_Week

Vì vậy, @daily về cơ bản nói rằng hãy chạy cái này mỗi phút: phút 0 giờ 0 của tất cả các ngày_of_month của tất cả các tháng của tất cả các ngày_of_week

Vì vậy, trường hợp của bạn được chạy này mỗi phút: phút 0 giờ 10 của tất cả các ngày_of_month của all_months của tất cả các ngày_of_week. Bản dịch này ở định dạng công việc định kỳ sang:

0 10 * * *

Cách kích hoạt và thử lại đúng cách thực hiện dag khi bạn phụ thuộc vào một sự kiện bên ngoài để hoàn thành việc thực hiện

  1. bạn có thể kích hoạt luồng gió từ một sự kiện bên ngoài bằng cách sử dụng lệnh airflow trigger_dag. điều này có thể xảy ra nếu một số cách bạn có thể kích hoạt tập lệnh lambda / tập lệnh python để nhắm mục tiêu luồng không khí của bạn.

  2. Nếu bạn không thể kích hoạt dag bên ngoài, thì hãy sử dụng toán tử cảm biến như OP đã làm, đặt poke_time cho nó và đặt số lần thử lại cao hợp lý.


Cám ơn vì cái này. Ngoài ra nếu tôi muốn kích hoạt các tác vụ dựa trên sự kiện chứ không phải thời gian, tức là ngay khi phân vùng dữ liệu mới có sẵn trong nguồn `AWS Athena Bàn`, tác vụ tiếp theo sẽ được kích hoạt. Sau đó, làm thế nào để tôi lên lịch. Là mã hiện tại của tôi đủ apt.
pankaj

@pankaj, tôi chỉ thấy hai lựa chọn thay thế. Tôi không biết nhiều về aws athena, nhưng bạn có thể kích hoạt luồng gió từ một sự kiện bên ngoài bằng cách sử dụng lệnh airflow trigger_dag. điều này có thể xảy ra nếu một số cách bạn có thể kích hoạt tập lệnh lambda / tập lệnh python để nhắm mục tiêu luồng không khí của bạn.
Bernardo bắt đầu hồi sinh

sự thay thế khác ít nhiều là những gì bạn đang làm, bởi vì bạn không có trình kích hoạt dựa trên sự kiện, bạn cần kiểm tra định kỳ nếu sự kiện này xảy ra. Vì vậy, việc sử dụng giải pháp hiện tại này sẽ được thiết lập một công việc định kỳ trong một vài giờ để chạy dag trong một vài phút ... nhiều người sẽ thất bại nhưng nó sẽ có thể bắt kịp khá nhanh sau khi sự kiện xảy ra
Bernardo bắt đầu hồi

@Bernado, tôi đã tìm ra gói trong Airflow được gọi AwsGlueCatalogPartitionSensorcùng với lệnh luồng khí {{ds_nodash}}cho phân vùng thoát. Câu hỏi của tôi sau đó làm thế nào để lên lịch này.
pankaj

@Benado, Bạn có thể xem mã của tôi nơi tôi đã triển khai kiểm tra được đề cập ở trên và đưa ra đầu vào của bạn
pankaj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.