我有一个DAG,该DAG从2015年1月1日开始一直运行到今天,每天安排。 DAG中的任务不是“过去依赖”的,这意味着在回填期间,它们可以按任何日期顺序执行。
如果我需要在DAG中回填任务,请使用UI清除所有任务实例(从今天到过去),然后所有DAG运行都会切换到“正在运行”状态,并且该任务将从2015年1月1日开始回填到今天。任务很耗时,因此即使由多个线程/工作人员并行执行,回填也只能在几天内完成。
问题在于,调度员在回填完成之前不会为明天,后天等添加新的“ DAG运行”,因此我们无法及时计算新的日期数据。有什么方法可以优先处理新任务,并在新任务完成后继续回填?
P.S。也可以使用“气流回填” CLI进行回填,但是这种方法有其自身的问题,因此现在我对上述回填技术很感兴趣。
答案 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)