Airflow 不遵循调度配置执行
在 Airflow 的使用过程中,曾多次遇到令人惊奇的现象,其中之一便是它没有按照 dag 中的配置执行。
可能你也会遇到这样的情况,为什么配置了 schedule_interval
和 start_date
,但是依旧没有按照调度配置的时间自动执行。
举个栗子
比如我这么配:
1 | from datetime import datetime, timedelta, timedelta |
照理说它应该按照配置中写的,每分钟执行一次操作。可是它没有,是它变心了吗?
不,不是的。
这究竟是为什么
Airflow sets execution_date based on the left bound of the schedule period it is covering, not based on when it fires (which would be the right bound of the period) .
原因在于 Airflow 是个有原则的程序,它有个窗口的概念,会把 start_date 开始后,符合 schedule_interval 定义的第一个时间点记为 execution_date,但是会在下个时间点到达时才开始运行。也就是说由于这个窗口的原因,last run 会滞后一个周期。
所以,按上面的配置来说,每次当 scheduler 读到了这段 DAG,它会拿小本本记下 start_date 和每分钟执行的操作,准备在下一分钟开始执行了。但是当下一分钟来临的时候,它看了看表,嗯!start_date + 1,那么 execution_date 也 + 1,于是把小本本上的 start_date 划掉重写。所以 start_date 在不断被覆盖的过程中,任务没有像我们预想中的在调度奔跑,反而一直是挂起状态。
这可咋整啊
那么如何才能真正地让它规律地执行呢?
将 start_date 往前错位到上一个周期
什么意思呢?假如本例中的每分钟执行一次,那就将 start_date 调整到上一分钟的状态
‘start_date’: datetime.now()
‘start_date’: datetime.now() - timedelta(minutes=1)
这下 scheduler 就可以在小本本工工整整地记录每一次调度计划,而不用写了划,划了写,把小本本涂得黑黑的了!
如果你的 dag 趁你不注意卡在running 状态下不能动弹,或许你可以改改调度时间或周期。
或者试试参考这篇文章:Airflow 居然趁服务器不注意卡在 running 状态不执行