Airflow实战——Time Zones
导读
datetime对象与时区
Python中一般使用datetime对象表示时间,datetime有一个属性tzinfo,代表了时区。如果在构造datetime对象的时候配置了tzinfo,那么这个datetime对象就是“aware”的,反之则被称为“naive”的。下面的两个例子依次构造了“aware”和“naive”的datetime对象:
import pendulum
local_tz = pendulum.timezone("Europe/Amsterdam")
date_aware = datetime(2022, 1, 1, tzinfo=local_tz),
date_naive = datetime(2022, 1, 1)
同样是表示2022年1月1日,显然,“aware”的datetime对象很明确,没有歧义,而“naive”的datetime对象则令人困惑,东八区的2022年1月1日和西八区的2022年1月1日整整差了16个小时!
在可能的情况下,尽量使用“aware”的datetime对象,这能够省却很多麻烦。
Airflow是如何处理时区的
Airflow内部使用的都是“aware”的datetime对象,如果用户在自己的代码中用了“naive”的datetime对象,Airflow会根据airflow.cfg配置文件中的core->default_timezone配置决定“native”的datetime对象的时区。这个配置的默认值为“utc”。
为了方便用户在代码中正确地使用时区,Airflow提供了一个工具类——timezone,该类提供了很多跟时区有关的方法,比如用来区分“aware”和“naive”的datetime对象的“timezone.is_localized()”和“timezone.is_naive()”方法,再比如用来获取UTC时区当前时间的“timezone.utcnow()”方法。
Airflow在内部会把datetime对象转成UTC时区,用户无法改变这个行为。统一使用UTC时区方便了不同时区的用户一起使用Airflow。这样做的另一个不那么明显的好处是避免引入DST(夏令时),DST时区的时钟在春季会往前调一个小时,到了秋季再调回来。这在很多时候会造成混乱。
用户可以指定DAG使用DST时区,尽管DST时区的时间在内部会被Airflow转成UTC时区,但这不代表用户能放心大胆地使用DST时区。我们用两个例子来说明这一点:
用户采用“0 0 * * *”的“cron expression”来配置DAG的“schedule_interval”
用户采用“timedelta(days=1)”来配置DAG的“schedule_interval”并且“start_date”为2022年1月1日
假设时区是“US/Eastern”(属于DST时区),那么这个DAG在夏令时会在每天04:00(UTC时区)运行,而在冬令时会在每天05:00(UTC时区)运行。
假设时区是“US/Eastern”(属于DST时区),那么这个DAG会一直在每天05:00(UTC时区)运行。这是因为开始的日期是冬令时,所以第一次运行肯定在05:00(UTC时区),此后每次的开始时间都是在前一天的基础上加一天,从而一直是05:00(UTC时区)。
通过上面两个例子的对比,我们能够很清晰地看到DST时区的复杂和难用。除非明确地知道自己用DST时区要做什么,否则不推荐使用。
Web UI的时区显示
当我们使用Airflow Webserver时,可以在界面上调节时区,此时UI的显示就会根据选择的时区进行调整。调节时区的方法是点击右上角的时间,在下拉菜单中选择合适的时区,如下图所示:

下拉菜单中的“UTC”是Airflow内部的UTC时区,“Server”是配置文件airflow.cfg中core->default_timezone配置决定的时区。“Local”是Airflow从浏览器获取的时区。如果这3个时区不能满足要求,还可以从“Other”中挑选合适的时区。
假设我们把时区改成“Local”,在上面的图中即CST时区。此时如果进入某个DAG的“Tree View”界面,把鼠标悬停在其中任何一个DAG Run/Task Instance上面,就能从浮动框中发现针对CST时区的显示优化:


添加 家长论坛微信
全部 0条评论