在Airflow中,我希望作业可以在非UTC时区中的每天特定时间运行。我该如何安排时间?
问题在于,一旦触发了夏令时,我的工作就会开始工作一个小时或太晚。在Airflow文档中,这似乎是一个已知问题:
如果您设置了cron时间表,Airflow会假设您始终希望完全在同一时间运行。然后它将忽略夏令时。因此,如果您有一个时间表,说在每天08:00 GMT + 1的间隔结束时运行,则无论是否设置了夏时制,它都将始终在08:00 GMT + 1间隔的末尾运行。
还有其他人遇到这个问题吗?有没有解决的办法?当然,最佳实践不能是在夏时制发生后更改所有计划的时间吗?
谢谢。
从Airflow 1.10开始,可以使用时区感知datetime对象指定来定义时区感知DAG start_date。要使Airflow始终计划DAG的运行(无论是否可能设置夏令时),请使用cron表达式指定schedule_interval。要使DAG以固定的间隔运行(无论是否可能设置夏令时),请使用datetime.timedelta()指定schedule_interval。
例如,考虑以下代码,该代码首先使用cron表达式调度两个连续的DAG运行,然后使用固定的间隔来执行相同的操作。
import pendulum
from airflow import DAG
from datetime import datetime, timedelta
START_DATE = datetime(
year=2019,
month=10,
day=25,
hour=8,
minute=0,
tzinfo=pendulum.timezone('Europe/Kiev'),
)
def gen_execution_dates(start_date, schedule_interval):
dag = DAG(
dag_id='id', start_date=start_date, schedule_interval=schedule_interval
)
execution_date = dag.start_date
for i in range(1, 3):
execution_date = dag.following_schedule(execution_date)
print(
f'[Run {i}: Execution Date for "{schedule_interval}"]:',
dag.timezone.convert(execution_date),
)
gen_execution_dates(START_DATE, '0 8 * * *')
gen_execution_dates(START_DATE, timedelta(days=1))
Run Code Online (Sandbox Code Playgroud)
运行代码将产生以下输出:
[Run 1: Execution Date for "0 8 * * *"]: 2019-10-26 08:00:00+03:00
[Run 2: Execution Date for "0 8 * * *"]: 2019-10-27 08:00:00+02:00
[Run 1: Execution Date for "1 day, 0:00:00"]: 2019-10-26 08:00:00+03:00
[Run 2: Execution Date for "1 day, 0:00:00"]: 2019-10-27 07:00:00+02:00
Run Code Online (Sandbox Code Playgroud)
对于区域[欧洲/基辅],2019年的夏时制时间于2019-10-27的03:00:00 + 03:00结束。也就是说,在我们的示例中,运行1和运行2之间。
前两个输出行显示,对于以cron表达式排定的DAG运行,第一次运行和第二次运行均排定为08:00(尽管在不同的时区:东欧夏季时间(EEST)和东欧时间(EET)分别)。
最后两行输出显示,对于以固定间隔安排的DAG运行,第一次运行计划为08:00(EEST),第二次运行恰好安排在1天(24小时)之后,即07:00 (EET)由于采用了夏令时开关。
下图说明了该示例:
| 归档时间: |
|
| 查看次数: |
887 次 |
| 最近记录: |