Apache Airflow调度程序不会在计划时触发DAG

时间:2016-11-21 06:32:49

标签: python apache cron directed-acyclic-graphs airflow

当我计划每天在特定时间运行DAG时,DAG执行根本不会发生。 但是,当我重新启动Airflow网络服务器和调度程序时,DAG在该特定日期的预定时间执行一次,并且从第二天开始不执行。 我使用的是带有python 2.7.6的Airflow版本v1.7.1.3。 这里是DAG代码:

from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from datetime import datetime, timedelta

import time
n=time.strftime("%Y,%m,%d")
v=datetime.strptime(n,"%Y,%m,%d")
default_args = {
    'owner': 'airflow',
    'depends_on_past': True,
    'start_date': v,
    'email': ['airflow@airflow.com'],
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 1,
    'retry_delay': timedelta(minutes=10),

}

dag = DAG('dag_user_answer_attempts', default_args=default_args, schedule_interval='03 02 * * *')

# t1, t2 and t3 are examples of tasks created by instantiating operators
t1 = BashOperator(
    task_id='user_answer_attempts',
    bash_command='python /home/ubuntu/bigcrons/appengine-flask-skeleton-master/useranswerattemptsgen.py',
    dag=dag)

我做错了吗?

4 个答案:

答案 0 :(得分:11)

您的问题是为当前时间设置的start_date。 Airflow在间隔的 end 处运行作业,而不是开始。这意味着您的工作的第一次运行将在第一个间隔之后。

示例:

你做了一个匕首,并在午夜将它放在Airflow中。今天(20XX-01-01 00:00:00)也是start_date,但它是硬编码的("start_date":datetime(20XX,1,1))。计划间隔是每天,与您的一样(3 2 * * *)。

这个dag第一次排队等待执行是20XX-01-02 02:03:00,因为这是间隔期结束的时间。如果你看看当时正在运行的dag,它应该在schedule_date之后大约一天的开始日期时间。

您可以将start_date硬编码到日期,方法是确保动态日期比过去的间隔时间更长(在您的情况下) ,2天会很多)。如果您需要重新运行作业或回填(或结束dag),Airflow建议您使用静态start_dates。

有关回填的更多信息(这个常见的stackoverflow问题的反面),请查看文档或此问题: Airflow not scheduling Correctly Python

答案 1 :(得分:2)

检查以下内容:

  1. start_date 是过去的固定时间(不要使用 datetime.now())
  2. 如果您不想运行历史数据,请使用 catchup=false
  3. 要设置 DAG 运行的特定时间(例如每小时、每月、每天、在特定时间),请尝试使用 https://crontab.guru/#40_21_*_*_* 写下您需要的内容。
  4. 如果您认为 1、2、3 步都正确,但 DAG 没有运行。或者 DAG 可以每 xx 分钟运行一次,但在每天的时间间隔内甚至无法触发一次,尝试创建一个新的 python 文件,将您的 DAG 代码复制到那里,重命名它以使文件唯一,然后再次测试。可能是由于之前 DAG 运行的元数据与当前计划之间的不一致,气流调度程序感到困惑。

希望这有帮助!

答案 2 :(得分:0)

根据日程安排,您的DAG应该每天凌晨02:03运行。我的怀疑是start_date可能会影响它。你可以硬编码为'start_date':datetime.datetime(2016,11,01)并尝试。

答案 3 :(得分:-1)

很好的答案apathyman。 它对我的理解有很大帮助。我使用的是 days_ago(0),一旦我将其更改为 days_ago(1),调度程序就开始触发。