Airflow 1.10.10 不改dag_id直接改DAG的schedule_interval有何问题?
网上流传的“修改schedule_interval必须更换dag_id”的经验,本质是Airflow 1.10.x 版本系列的已知缺陷总结,并非绝对的操作铁则。你测试时顺利完成调度更新、未出现异常,只是因为测试场景刚好避开了缺陷的触发条件,不代表无实际风险。
历史运行数据引发的无提示批量补跑
Airflow 1.10.10的scheduler计算下一次触发时间时,会优先读取元数据库中存储的该dag_id的上次逻辑运行时间,再套用新的schedule_interval规则向后推算。如果你的DAG之前是@Daily调度,最后一次运行的逻辑时间距离你修改配置的时间已经有好几个小时,突然改成5分钟间隔时,scheduler会自动把这几个小时里所有符合新间隔的、本该生成却没生成的DAG run全部补建出来,直接触发批量任务重跑。这类操作没有任何弹窗提示,很多生产环境的批量任务误触发事故,都是这个逻辑引发的。你测试时没遇到这类问题,大概率是每次调整调度规则的间隔很短,两次配置修改之间的时间差远小于新的调度间隔,补建的实例数量极少,没有被注意到。调度粒度变更引发的上下文数据错乱
很多DAG的任务逻辑会强依赖和schedule_interval绑定的内置模板变量,比如{{ ds }}、{{ prev_ds }}、{{ data_interval_start }}。当你从日调度改成短周期调度后,新生成的DAG run的逻辑时间戳会和历史运行实例的时间序列逻辑断裂:旧的日调度实例的逻辑时间都是当日零点,新的短周期实例的逻辑时间会从之前最后一次日调度的时间点往后按新间隔切分,如果你有跨实例的依赖逻辑(比如取上一个运行实例的输出做计算),就会出现当前5分钟粒度的任务,拿到的是1天前的旧运行实例的数据,直接引发数据口径错误。如果任务逻辑里硬编码了和原调度粒度匹配的取数窗口,还会出现漏数、重复拉数的问题。元数据残留引发的调度状态异常
1.10.10版本本身存在已知的DAG run一致性校验缺陷:如果修改schedule_interval时,元数据库中还残留该dag_id的旧状态实例(比如处于queued、running状态的未完成任务),scheduler的调度锁、事件标记会沿用旧的规则计算新的触发时间,容易出现两类异常:要么是新间隔明明只有5分钟,scheduler却连续几个周期不触发新任务;要么是把新生成的符合预期的DAG run,因为不在旧调度规则的时间序列里,被校验逻辑判定为非法run,直接标记为skipped,导致任务根本没执行。这类异常不会在DAG解析阶段抛出明确的语法错误,只会藏在scheduler的运行日志里,排查成本极高。监控规则、前端展示的逻辑错位
你之前为该DAG配置的SLA阈值、任务延迟告警,都是基于原有的@Daily调度粒度设置的——比如设置任务要在提交后1小时内完成才算正常,改成5分钟间隔调度后,这套阈值不会自动跟着调整,会导致任务刚提交就被判定SLA超时,触发无意义的告警。同时Airflow UI上缓存的下一次运行时间,有时会沿用旧的调度规则计算,出现UI显示还有1天才触发、结果实际5分钟后就启动了的情况,容易误导运维判断。
之所以公开资料大多推荐修改dag_id来调整调度规则,核心是因为上述异常的触发概率和触发时的严重程度,在生产环境带着历史运行数据、自定义任务逻辑的场景下是不可控的。如果要在不修改dag_id的前提下调整schedule_interval,需要在修改配置后清理该dag的历史残留状态、重启scheduler重新初始化调度计算逻辑,才能尽量规避上述问题。
内容的提问来源于stack exchange,提问作者AvneeshAtri

