气流回填和新冲刺运行

时间:2018-07-31 15:40:32

标签: python scheduled-tasks airflow

我有一个DAG,该DAG从2015年1月1日开始一直运行到今天,每天安排。 DAG中的任务不是“过去依赖”的,这意味着在回填期间,它们可以按任何日期顺序执行。

如果我需要在DAG中回填任务,请使用UI清除所有任务实例(从今天到过去),然后所有DAG运行都会切换到“正在运行”状态,并且该任务将从2015年1月1日开始回填到今天。任务很耗时,因此即使由多个线程/工作人员并行执行,回填也只能在几天内完成。

问题在于,调度员在回填完成之前不会为明天,后天等添加新的“ DAG运行”,因此我们无法及时计算新的日期数据。有什么方法可以优先处理新任务,并在新任务完成后继续回填?

P.S。也可以使用“气流回填” CLI进行回填,但是这种方法有其自身的问题,因此现在我对上述回填技术很感兴趣。

1 个答案:

答案 0 :(得分:4)

类似于对您的问题的评论,当我回填大型数据库时,解决此问题的方法是让dag生成器基于connection_created_on创建三个dag(两个backfill,一个正在进行)和start_date值。

正在进行的dag每小时运行一次,并与connection_created_on值在同一天的午夜开始。然后,这两个回填广告从当前月份的第一天开始每天拉,然后从start_date的第一个月开始每月拉。在这种情况下,我知道我们总是希望从本月的第一天开始,并且范围长达一个月的数据足够小,可以汇总到一起,因此为了方便起见,我将其分为这三种类型。 >

def create_dag(dag_id,
           schedule,
           db_conn_id,
           default_args,
           catchup=False,
           max_active_runs=3):

    dag = DAG(dag_id,
              default_args=default_args,
              schedule_interval=schedule,
              catchup=catchup,
              max_active_runs=max_active_runs
              )
    with dag:
        kick_off_dag = DummyOperator(task_id='kick_off_dag')

    return dag

db_conn_id = 'my_first_db_conn'
connection_created_on = '2018-05-17 12:30:54.271Z'

hourly_id = '{}_to_redshift_hourly'.format(db_conn_id)
daily_id = '{}_to_redshift_daily_backfill'.format(db_conn_id)
monthly_id = '{}_to_redshift_monthly_backfill'.format(db_conn_id)

start_date = '2005-01-01 00:00:00.000Z'
start_date = datetime.strptime(start_date, '%Y-%m-%dT%H:%M:%S.%fZ')
start_date = datetime(start_date.year, start_date.month, 1)

cco_datetime = datetime.strptime(connection_created_on, '%Y-%m-%dT%H:%M:%S.%fZ')
hourly_start_date = datetime(cco_datetime.year, cco_datetime.month, cco_datetime.day)
daily_start_date = hourly_start_date - timedelta(days=(cco_datetime.day-1))
daily_end_date = hourly_start_date - timedelta(days=1)
monthly_start_date = start_date if start_date else hourly_start_date - timedelta(days=365+cco_datetime.day-1)
monthly_end_date = daily_start_date

globals()[hourly_id] = create_dag(hourly_id,
                                  '@hourly',
                                  db_conn_id,
                                  {'start_date': hourly_start_date,
                                   'retries': 2,
                                   'retry_delay': timedelta(minutes=5),
                                   'email': [],
                                   'email_on_failure': True,
                                   'email_on_retry': False},
                                  catchup=True,
                                  max_active_runs=1)

globals()[daily_id] = create_dag(daily_id,
                                 '@daily',
                                 db_conn_id,
                                 {'start_date': daily_start_date,
                                  'end_date': daily_end_date,
                                  'retries': 2,
                                  'retry_delay': timedelta(minutes=5),
                                  'email': [],
                                  'email_on_failure': True,
                                  'email_on_retry': False},
                                 catchup=True)

globals()[monthly_id] = create_dag(monthly_id,
                                   '@monthly',
                                   db_conn_id,
                                   {'start_date': monthly_start_date,
                                    'end_date': monthly_end_date,
                                    'retries': 2,
                                    'retry_delay': timedelta(minutes=5),
                                    'email': [],
                                    'email_on_failure': True,
                                    'email_on_retry': False},
                                   catchup=True)