簡體   English   中英

Airflow ExternalTaskSensor 卡住

[英]Airflow ExternalTaskSensor gets stuck

我正在嘗試使用 ExternalTaskSensor,但它卡在了另一個 DAG 的任務上,該任務已經成功完成。

在這里,第一個 DAG“a”完成了它的任務,然后應該觸發通過 ExternalTaskSensor 的第二個 DAG“b”。 相反,它會卡在查找 a.first_task 上。

第一個 DAG:

import datetime
from airflow import DAG
from airflow.operators.python_operator import PythonOperator

dag = DAG(
    dag_id='a',
    default_args={'owner': 'airflow', 'start_date': datetime.datetime.now()},
    schedule_interval=None
)

def do_first_task():
    print('First task is done')

PythonOperator(
    task_id='first_task',
    python_callable=do_first_task,
    dag=dag)

第二個 DAG:

import datetime
from airflow import DAG
from airflow.operators.python_operator import PythonOperator
from airflow.operators.sensors import ExternalTaskSensor

dag = DAG(
    dag_id='b',
    default_args={'owner': 'airflow', 'start_date': datetime.datetime.now()},
    schedule_interval=None
)

def do_second_task():
    print('Second task is done')

ExternalTaskSensor(
    task_id='wait_for_the_first_task_to_be_completed',
    external_dag_id='a',
    external_task_id='first_task',
    dag=dag) >> \
PythonOperator(
    task_id='second_task',
    python_callable=do_second_task,
    dag=dag)

我在這里錯過了什么?

ExternalTaskSensor假定您依賴於具有相同執行日期的 dag 運行中的任務。

這意味着在您的情況下,dag ab需要按相同的時間表運行(例如,每天上午 9:00 或 w/e)。

否則,您需要在實例化ExternalTaskSensor時使用execution_deltaexecution_date_fn

這是操作員本身內部的文檔,以幫助進一步澄清:

:param execution_delta: time difference with the previous execution to
    look at, the default is the same execution_date as the current task.
    For yesterday, use [positive!] datetime.timedelta(days=1). Either
    execution_delta or execution_date_fn can be passed to
    ExternalTaskSensor, but not both.

:type execution_delta: datetime.timedelta


:param execution_date_fn: function that receives the current execution date
    and returns the desired execution date to query. Either execution_delta
    or execution_date_fn can be passed to ExternalTaskSensor, but not both.

:type execution_date_fn: callable

為了澄清我在這里和其他相關問題上看到的內容,dags 不一定必須按相同的時間表運行,如已接受的答案中所述。 dag 也不需要具有相同的start_date 如果您在沒有execution_deltaexecution_date_fn情況下創建ExternalTaskSensor任務,則兩個 dag 需要具有相同的執行日期 碰巧的是,如果兩個 dag 具有相同的計划,則每個間隔中的計划運行將具有相同的執行日期。 我不確定手動觸發的預定 dag 運行的執行日期是什么。

為了讓這個例子起作用,dag bExternalTaskSensor任務需要一個execution_deltaexecution_date_fn參數。 如果使用execution_delta參數,則應該是b的執行日期 - execution_delta = a的執行日期。 如果使用execution_date_fn ,則該函數應返回a的執行日期。

如果您使用的是TriggerDagRunOperator ,然后使用ExternalTaskSensor來檢測該 dag 何時完成,您可以執行一些操作,例如使用TriggerDagRunOperatorexecution_date參數將主 dag 的執行日期傳遞給觸發日期,例如execution_date='{{ execution_date }}' . 那么兩個 dag 的執行日期將相同,並且您不需要每個 dag 的計划都相同,或者使用execution_deltaexecution_date_fn傳感器參數。

以上是在 Airflow 1.10.9 上編寫和測試的

從 Airflow v1.10.7 開始,tomcm 的回答不正確(至少對於這個版本)。 如果它們沒有相同的計划,則應使用execution_deltaexecution_date_fn來確定外部 DAG 的日期和計划。

從我的成功案例來看:

default_args = {
    'owner': 'xx',
    'retries': 2,
    'email': ALERT_EMAIL_ADDRESSES,
    'email_on_failure': True,
    'email_on_retry': False,
    'retry_delay': timedelta(seconds=30),
    # avoid stopping tasks after one day
    'depends_on_past': False,
}

dag = DAG(
    dag_id = dag_id,
    # get the datetime type value
    start_date = pendulum.strptime(current_date, "%Y, %m, %d, %H").astimezone('Europe/London').subtract(hours=1),
    description = 'xxx',
    default_args = default_args,
    schedule_interval = timedelta(hours=1),
    )
...
    external_sensor= ExternalTaskSensor(
            task_id='ext_sensor_task_update_model',
            external_dag_id='xxx',
            external_task_id='xxx'.format(log_type),
            # set the task_id to None because of the end_task
            # external_task_id = None,
            dag=dag,
            timeout = 300,
            )
...

您可以等到任務成功自動觸發。 不要手動執行,start_date 會有所不同。

Airflow 默認查找相同的執行日期和時間戳。 如果我們使用 execution_date_fn 參數,我們必須返回要查找的時間戳值列表。 在內部,傳感器將查詢氣流的 task_instance 表,以檢查作為參數提供的 dagid、taskid、狀態和執行日期時間戳的 dag 運行。 因此,如果我們使用 None 計划,則必須手動觸發 dag,在這種情況下,日期時間戳可能是任何可能的值。 我在這里詳細解釋過: https : //link.medium.com/QzXm21asokb

我創建了一個繼承 ExternalTask​​Sensor 的新傳感器,它可用於監控無計划的 dag。 您可以在下面的 repo 中找到代碼。 https://github.com/Deepaksai1919/AirflowTaskSensor

我也遇到了這個問題,但在我的例子中,兩個 DAG 都使用相同的schedule_interval ,所以上述建議都沒有幫助。

原來這是一個 Airflow 錯誤。 external_task_id / external_task_ids字段中的模板目前在 v2.2.4 中已損壞: https://github.com/apache/airflow/issues/22782

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM