Airflow görevini yalnızca AWS athena tablosundaki yeni bölüm / veriler python'da DAG kullanarak tetiklendiğinde nasıl tetikleyebilirim?


9

Aşağıdaki gibi bir scenerio var:

  1. A Task 1ve Task 2yalnızca yeni veriler kaynak tabloda (Athena) kullanılabilir olduğunda tetikleyin . Görev1 ve Görev2 için tetikleyici, gün içinde yeni bir veri bölümü olduğunda gerçekleşmelidir.
  2. Tetik Task 3sadece tamamlanması üzerine Task 1veTask 2
  3. Tetikleyicinin Task 4yalnızcaTask 3

resim açıklamasını buraya girin

Kodum

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)

Bunu başarmanın en iyi yolu nedir?


bu çözümle ilgili herhangi bir problemin mi var?
Bernardo,

@ Bernardostearnsreisen, Bazen Task1ve Task2döngü halinde gidiyor. Benim için veriler Athena kaynak tablosunda 10 AM CET'e yüklenir.
pankaj

yani bir döngü devam ederse, hava akışı Görev1 ve Görev2'yi başarılı olana kadar birçok kez yeniden dener?
Bernardo,

@Bernardostearnsreisen, yup tam olarak
pankaj

1
@Bernardostearnsreisen, ödül nasıl ödüllendirileceğini bilmiyordum :)
pankaj

Yanıtlar:


1

Sorunuzun iki önemli sorunu ele aldığına inanıyorum:

  1. schedule_intervalaçık bir şekilde yapılandırmayı unutma böylece @daily beklemediğiniz bir şey kuruyor.
  2. Yürütmeyi tamamlamak için harici bir olaya bağımlı olduğunuzda, dag yürütmesini düzgün bir şekilde nasıl tetikleyebilir ve yeniden deneyebilirsiniz?

Kısa cevap: Schedule_interval'ınızı açıkça bir cron iş formatıyla ayarlayın ve zaman zaman kontrol etmek için sensör operatörlerini kullanın

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)

nerede startimegünlük görev başlayacak saat kaç, endtimebir olay başarısız oldu ve olarak işaretleme önce yapıldığını olmadığını kontrol etmelidir günün son zaman nedir poke_timesenin aralığıdır sensor_operatorolay olduysa kontrol edecektir.

Dag'ınızı yaptığınız gibi ayarladığınızda cron işini açıkça nasıl ele@daily alırsınız:

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

dan dokümanlar , size aslında yapıyor olması edilir görebilirsiniz: @daily - Run once a day at midnight

Bu şimdi zaman aşımı hatası aldığınız anlamına gelir 'retries': 1ve ve ayarladığınız için 5 dakika sonra başarısız olur 'retry_delay': timedelta(minutes=5). Bu yüzden gece yarısında dag çalıştırmaya çalışır, başarısız olur. 5 dakika sonra tekrar dener ve tekrar başarısız olur, bu nedenle başarısız olarak işaretlenir.

Temel olarak @daily run aşağıdakilerin örtük bir cron işini ayarlıyor:

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

Cron iş biçimi aşağıdaki biçimdedir ve *"all" demek istediğinizde değeri olarak ayarlarsınız .

Minute Hour Day_of_Month Month Day_of_Week

Yani @daily temelde bunu her çalıştır diyor: tüm günlerin dakika 0 saat 0'ı_gün_ayısı

Yani davanız bunu her gün çalıştırır: tüm günlerin dakika 0 saat 10'u Bu, cron iş biçiminde şu dile çevrilir:

0 10 * * *

Yürütmeyi tamamlamak için harici bir olaya bağımlı olduğunuzda, dag yürütmesini düzgün bir şekilde nasıl tetikleyebilir ve yeniden deneyebilirsiniz?

  1. komutunu kullanarak harici bir olaydan gelen hava akışında bir dag tetikleyebilirsiniz airflow trigger_dag. hava akışı örneğinizi hedeflemek için bir lambda işlevi / python betiğini nasıl tetikleyebileceğiniz bazı durumlarda bu mümkün olacaktır.

  2. Dag'ı harici olarak tetikleyemiyorsanız, OP'nin yaptığı gibi bir sensör operatörü kullanın, ona bir poke_time ayarlayın ve makul sayıda yüksek yeniden deneme ayarlayın.


Bunun için teşekkürler. Ayrıca görevleri zaman yerine olay yerine göre tetiklemek istersem yani `` AWS Athena Tables '' kaynağında yeni veri bölümü hazır olduğunda bir sonraki görev tetiklenmelidir. O zaman nasıl programlayacağım. Mevcut kodum yeterli mi?
pankaj

@pankaj, sadece iki alternatif görüyorum. Aws athena hakkında fazla bir şey bilmiyorum, ama komutu kullanarak harici bir olaydan hava akışında bir dag tetikleyebilirsiniz airflow trigger_dag. hava akışı örneğinizi hedeflemek için bir lambda işlevi / python betiğini nasıl tetikleyebileceğiniz bazı durumlarda bu mümkün olacaktır.
Bernardo,

diğer alternatif aşağı yukarı yaptığınız şeydir, çünkü olaya dayalı bir tetikleyiciniz olmadığından, bu olayın olup olmadığını düzenli olarak kontrol etmeniz gerekir. Bu yüzden bu mevcut çözümü kullanmak, birkaç saat boyunca cron işi ayarlayacaktır, çok yüksek bir sıklıkta dag çalıştırır ... birçoğu başarısız olur, ancak olay gerçekleştikten sonra oldukça hızlı bir şekilde yakalanabilir
Bernardo, reisen

@Bernado, bölüm çıkışları için AwsGlueCatalogPartitionSensorhava akımı komutu ile birlikte çağrılan Airflow paketini anladım {{ds_nodash}}. Benim sorum o zaman nasıl planlamak için.
pankaj

@Benado, Yukarıda belirtilen kontrolü uyguladığım ve girişlerinizi verdiğim koduma bakabilir misiniz
pankaj
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.