วิธีการทริกเกอร์ภารกิจ Airflow เฉพาะเมื่อมีการแบ่งพาร์ติชัน / ข้อมูลใหม่ในตาราง AWS athena โดยใช้ DAG ในหลาม


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)

อะไรคือวิธีที่เหมาะสมที่สุดในการบรรลุเป้าหมาย


คุณมีปัญหากับวิธีนี้หรือไม่?
เบอร์นาร์โดสเติร์นส์เปิดตัว

@ Bernardostearnsreisen บางครั้งTask1และTask2ไปในวง สำหรับฉันข้อมูลถูกโหลดในตารางแหล่ง Athena 10:00 AM CET
pankaj

เกิดขึ้นในวงคุณหมายถึงการไหลของอากาศพยายาม Task1 และ Task2 หลายครั้งจนกว่ามันจะเกิน?
เบอร์นาร์โดสเติร์นส์เปิดตัว

@Bernardostearnsreisen, yup อย่างแน่นอน
pankaj

1
@Bernardostearnsreisen ผมไม่ทราบวิธีการที่ได้รับรางวัลรางวัล :)
Pankaj

คำตอบ:


1

ฉันเชื่อว่าคำถามของคุณแก้ไขปัญหาสำคัญสองประการ:

  1. ลืมที่จะกำหนดค่าschedule_intervalในวิธีที่ชัดเจนดังนั้น @daily กำลังตั้งค่าบางสิ่งที่คุณไม่ได้คาดหวัง
  2. วิธีการทริกเกอร์และลองการดำเนินการ dag ใหม่อีกครั้งอย่างถูกต้องเมื่อคุณขึ้นอยู่กับเหตุการณ์ภายนอกเพื่อดำเนินการให้เสร็จสิ้น

คำตอบสั้น ๆ : ตั้งค่า schedule_interval ของคุณอย่างชัดเจนด้วยรูปแบบงาน 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 อย่างชัดเจน ทุกครั้งที่คุณตั้งค่า dag ตามที่@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)ดังนั้นจึงพยายามเรียกใช้ 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 ของทุกวัน _ ของ _ เดือนของทุกเดือนของทุกวัน _ ของ _ วัน

ดังนั้นกรณีของคุณจะดำเนินการนี้ทุก ๆ นาที 0 ชั่วโมง 10 ทุกวัน _ ของ _ ทุกวัน _ ของทุกวัน _ วัน _ สัปดาห์ สิ่งนี้แปลในรูปแบบงาน cron เป็น:

0 10 * * *

วิธีการทริกเกอร์และลองการดำเนินการ dag ใหม่อีกครั้งอย่างถูกต้องเมื่อคุณขึ้นอยู่กับเหตุการณ์ภายนอกเพื่อดำเนินการให้เสร็จสิ้น

  1. คุณสามารถเรียก dag airflow trigger_dagในการไหลของอากาศจากเหตุการณ์ภายนอกโดยใช้คำสั่ง สิ่งนี้จะเป็นไปได้หากมีวิธีที่คุณสามารถเรียกใช้ฟังก์ชัน lambda / สคริปต์ไพ ธ อนเพื่อกำหนดเป้าหมายอินสแตนซ์การไหลเวียนอากาศของคุณ

  2. หากคุณไม่สามารถเรียกใช้ dag จากภายนอกได้ให้ใช้ตัวดำเนินการเซ็นเซอร์เช่น OP ทำแล้วตั้งค่า poke_time ไว้แล้วตั้งค่าจำนวนครั้งที่เหมาะสม


ขอบคุณสำหรับสิ่งนี้. นอกจากนี้หากฉันต้องการทริกเกอร์งานตามเหตุการณ์มากกว่าเวลาเช่นเมื่อเร็ว ๆ นี้พาร์ทิชันข้อมูลใหม่จะพร้อมใช้งานในแหล่งงาน 'AWS Athena Tables`' ถัดไปควรเรียกใช้งาน แล้วฉันจะกำหนดเวลาได้อย่างไร รหัสปัจจุบันของฉันเหมาะสมหรือไม่
pankaj

@pankaj ฉันเห็นเพียงสองทางเลือก ผมไม่ทราบว่ามากเกี่ยวกับ AWS Athena แต่คุณสามารถเรียก dag airflow trigger_dagในการไหลของอากาศจากเหตุการณ์ภายนอกโดยใช้คำสั่ง สิ่งนี้จะเป็นไปได้หากมีวิธีที่คุณสามารถเรียกใช้ฟังก์ชัน lambda / สคริปต์ไพ ธ อนเพื่อกำหนดเป้าหมายอินสแตนซ์การไหลเวียนอากาศของคุณ
เบอร์นาร์โดสเติร์นส์เกิดขึ้นอีก

อีกทางเลือกหนึ่งคือสิ่งที่คุณทำมากขึ้นหรือน้อยลงเนื่องจากคุณไม่มีทริกเกอร์ตามเหตุการณ์คุณต้องตรวจสอบเป็นระยะว่ากิจกรรมนี้เกิดขึ้นหรือไม่ ดังนั้นการใช้วิธีแก้ปัญหาในปัจจุบันนี้จะถูกกำหนดให้เป็นงาน cron เป็นระยะเวลาหนึ่งที่จะทำงานช้าลงในเวลาไม่กี่นาที ... หลายคนจะล้มเหลว แต่มันจะสามารถจับได้อย่างรวดเร็วหลังจากเหตุการณ์เกิดขึ้น
Bernardo stearns reisen

@Bernado ฉันได้พบแพ็คเกจใน Airflow ที่เรียกAwsGlueCatalogPartitionSensorพร้อมกับคำสั่ง airflow {{ds_nodash}}สำหรับการออกจากพาร์ติชัน คำถามของฉันแล้ววิธีกำหนดเวลานี้
pankaj

@ Benado, คุณสามารถดูรหัสของฉันที่ฉันได้ดำเนินการตรวจสอบดังกล่าวข้างต้นและให้อินพุตของคุณ
pankaj
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.