Airflow 时区故障

关于时区的整理

一旦涉及跨服务器的服务,那么难免碰到时区同步的问题,而 Web 服务很少是单机提供的,因此做现在的 Web 架构中应当处理好时区问题。

之前在写业务接口的时候,将系统所有的入口和出口都做了时区转换的处理,在内部各函数之间使用无时区的 datetime 格式传递时间,避免一些常见的小错误:

  1. 单方面使用 arrow 库的对象
  2. 将带时区和不带时区的 datetime 作比较
  3. 将零时区的日期入库导致差错

结果今天 airflow 从 1.8.0 升级到 1.9.0,也发生了时区问题,具体表现为 scheduler 成功调度了一个 DAG,但是却没有真正生成 DAG RUN,手动执行 airflow run 也无法执行。所以需要基于几个原则进行排查,看错误发生在哪一步:

  1. 所有的服务(包括数据库、终端 UI)都是有时区的
  2. 服务入口对时间进行时区转换,拒绝不带时区的时间,保证服务内部时区的统一。
  3. 服务出口为带时区的时间。
  4. 如果大家都遵循同一种规范(默认时区),则可以接受和传递不带时区的时间,但这事实上是不可能的,因为终端 UI 的默认时区是不可控的。

目前的情况是:

  1. scheduler 按照零时区的时间进行调度,之前以 contab 格式运行的 DAG 都会偏差 8 小时。
  2. webserver 按照零时区的时间进行显示
  3. log 使用的是服务器的默认时区

至少需要使 scheduler 的调度正确,最好 webserver 也能显示正确。

解决方式是使 scheduler 使用正确的时区,在创建 TI、执行 run 指令的时候时间正确。

  1. 尝试通过 default_timezone = Asia/Shanghai 配置,但是未生效。
  2. 发现 default_timezone 是在 1.10 才能生效,但是该版本目前处于开发中,可能有其他问题。

结论:

  1. 由于时区问题,1.8 升级到 1.9以后会存在 8 小时的死时间,这段时间的任务会被认为已经执行过了,无法运行。
  2. 由于时区问题,需要在每天的指定小时运行的任务会延迟 8 小时。
  3. 在不改 DAG 的情况下,不能升级 1.9,需要继续使用 1.8。
坚持原创技术分享,您的支持将鼓励我继续创作!