Apache Airflow:在start_date之前执行了两次DAG

时间:2017-09-08 13:03:58

标签: airflow apache-airflow airflow-scheduler

.Hi所有人,

在Airflow UI中,我们试图了解如何在特定时间启动DAG运行,但我们总是在追赶模式下获得2次额外运行(即使禁用追赶)

示例

使用以下参数创建DAG运行

  • start_date:10:3​​0
  • execution_date:未定义
  • interval = 3分钟(来自.py文件)
  • catchup_by_default = False

在当前时间转动 ON开关:10:28 。我们得到的是Airflow触发2 DAG运行,执行时执行execute_date:

  • 10点24
  • 10时27

这两个DAG运行一个接一个地以追赶模式运行,这不是我们想要的:-(

我们做错了什么? 我们可能理解10:27运行(ETL概念),但我们没有得到10点24分: - (

感谢您的帮助:-)

详情:

操作系统:RedHat 7,Airflow v1.8.0

DAG python文件:

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


default_args = {
     'owner': 'aa',
     'depends_on_past': False,
     'start_date': datetime(2017, 9, 7, 10, 30),
     'run_as_user': 'aa'
}

dag = DAG(
    'dag3', default_args=default_args, schedule_interval=timedelta(minutes=3))
dag.catchup = False

create_command = "/script.sh "

t1 = BashOperator(
    task_id='task',
    bash_command='date',
    dag=dag)

3 个答案:

答案 0 :(得分:3)

我在SQLite上尝试使用Airflow v.1.8.0,python v.3.5,db。下面的DAG,在10:28取消,与你的非常相似,并且可以正常工作(只有一次运行,在10:33,10:30)。

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

def print_hello_3min():
    return ('Hello world! %s' % datetime.now())

dag = DAG('hello_world_3min', description='Simple tutorial DAG 3min',
          schedule_interval='*/3 * * * *',
          start_date=datetime(2017, 9, 18, 10, 30),
          catchup=False)

dummy_operator = DummyOperator(task_id='dummy_task_3min', retries=3, dag=dag)

hello_operator = PythonOperator(task_id='hello_task_3min',
                                python_callable=print_hello_3min, dag=dag)

dummy_operator >> hello_operator

答案 1 :(得分:0)

  

StackEdit一起写。

我不确定我的解决方案是否足够好,但是我想表达我的理解。 一起考虑两件事:

  1. schedule_interval模式,例如“每小时”,“每天”,“每周”,“每年”。

    • 每小时=(* 1 * * *)=“在每小时1的每一分钟。”
    • 每天=(0 1 * * *)=“在01:00。”
    • 每月=(0 1 1 * *)=“在每月1号的01:00。”
  2. 开始日期

    • 每小时=日期时间(2019、4、5、1、30)
    • 每天=日期时间(2019,4,5)
    • 每月= datetime(2019,4,1)

我的策略是通过将期望的开始日期和时间减去间隔模式的1个单位来设置[开始日期]。

示例:

  1. 要在 2019-4-5 01:00 开始第一份工作,并且间隔为每小时

    • schedule_interval模式= 每小时
    • 期望开始日期时间= 2019-4-5 01:00
    • 因此,开始日期= 2019-4-5 00:00
    • 每小时减一小时
    • CRON =(* 1 * * *),表示“在每小时1的每一分钟。”
    default_args = {
         'owner': 'aa',
         'depends_on_past': False,
         'start_date': datetime(2019, 4, 5, 0, 0),
         'run_as_user': 'aa'
    }    
    dag = DAG(
        'dag3', default_args=default_args, catchup = False, schedule_interval='* 1 * * *')
  1. 要在 2019-4-5 01:00 开始第一份工作,并且间隔为每天

    • schedule_interval模式= 每天
    • 期望开始日期时间= 2019-4- 5 01:00
    • 因此,开始日期= 2019-4- 4
    • 减去1天的天
    • CRON =(0 1 * * *),表示“在01:00。”
    default_args = {
        'owner': 'aa',
        'depends_on_past': False,
        'start_date': datetime(2019, 4, 4),
        'run_as_user': 'aa'
    }

    dag = DAG(
        'dag3', default_args=default_args, catchup = False, schedule_interval='0 1 * * *')
  1. 要在 2019-4-5 01:00 开始第一份工作,且间隔为每月

    • schedule_interval模式= 每月
    • 期望开始日期时间日期= 2019- 4-5 01:00
    • 因此,开始日期= 2019- 4-4
    • 减去1天的天
    • CRON =(0 1 1 * *),表示“每月1日的01:00”。
    default_args = {
         'owner': 'aa',
         'depends_on_past': False,
         'start_date': datetime(2019, 4, 4),
         'run_as_user': 'aa'
    }

    dag = DAG(
        'dag3', default_args=default_args, catchup = False, schedule_interval='0 1 1 * *')

到目前为止,该策略对我很有用,但是如果有人变得更好,请分享。

PS。我正在使用[https://crontab.guru]生成完美的cron计划。

答案 2 :(得分:0)

这似乎仅在提供timedelta作为时间表时发生。将您的计划时间间隔切换为cron格式,它将不再运行两次。