时区
默认情况下启用对时区的支持。 Airflow在内部和数据库中以UTC格式存储日期时间信息。 它允许您使用时区相关的计划运行DAG。 目前,Airflow不会将其转换为用户界面中的最终用户时区。 它始终以UTC显示。 此外,操作符中使用的模板也不会被转换。 时区信息是暴露出来的,由DAG的作者负责。
如果您的用户居住在多个时区,并且您希望根据每个用户的挂钟显示日期时间信息,这将非常方便。
即使您只在一个时区运行Airflow,在数据库中以UTC格式存储数据仍然是一种很好的做法(在Airflow成为时区之前也是如此,这也是建议的甚至是必需的设置)。 主要原因是夏令时(DST)。 许多国家都有DST系统,其中时钟在春季向前移动,在秋季向后移动。 如果您在当地工作,那么当转换发生时,您可能每年会遇到两次错误。 (钟摆和pytz文档更详细地讨论了这些问题。)这对于简单的DAG可能无关紧要,但如果您处于金融服务中,那么这是一个问题,在这些金融服务中您可以满足最后期限。
时区在<cite>airflow.cfg中</cite>设置。 默认情况下,它设置为utc,但您将其更改为使用系统设置或任意IANA时区,例如<cite>Europe / Amsterdam</cite> 。 它取决于<cite>钟摆</cite> ,它比<cite>pytz</cite>更准确。 安装Airflow时会安装Pendulum。
请注意,Web UI目前仅以UTC格式运行。
概念
天真并了解日期时间对象
Python的datetime.datetime对象具有tzinfo属性,可用于存储时区信息,表示为datetime.tzinfo的子类的实例。 设置此属性并描述偏移量时,可以识别日期时间对象。 否则,这是天真的。
您可以使用timezone.is_aware()和timezone.is_naive()来确定日期时间是否知晓或天真。
因为Airflow使用时区感知日期时间对象。 如果您的代码创建了datetime对象,那么他们也需要注意。
from airflow.utils import timezone
now = timezone . utcnow ()
a_date = timezone . datetime ( 2017 , 1 , 1 )
解释天真的日期时间对象
尽管Airflow完全可以识别时区,但它仍然可以在DAG定义中为<cite>start_dates</cite>和<cite>end_dates</cite>接受天真的日期时间对象。 这主要是为了保持向后兼容性。 如果遇到天真的<cite>start_date</cite>或<cite>end_date,</cite>则应用默认时区。 它以这样的方式应用,即假定天真日期时间已经在默认时区。 换句话说,如果您有<cite>欧洲/阿姆斯特丹</cite>的默认时区设置并创建<cite>日期时间(2017,1,1)</cite>的天真日期时间<cite>start_date</cite> ,则假定它是2017年1月1日阿姆斯特丹时间的<cite>start_date</cite> 。
default_args = dict (
start_date = datetime ( 2016 , 1 , 1 ),
owner = 'Airflow'
)
dag = DAG ( 'my_dag' , default_args = default_args )
op = DummyOperator ( task_id = 'dummy' , dag = dag )
print ( op . owner ) # Airflow
不幸的是,在DST转换期间,某些日期时间不存在或不明确。 在这种情况下,钟摆会引发异常。 这就是为什么在启用时区支持时应始终创建有意识的日期时间对象的原因。
实际上,这很少是一个问题。 Airflow可以让您了解模型和DAG中的日期时间对象,并且通常,新的日期时间对象是通过timedelta算法从现有对象创建的。 通常在应用程序代码中创建的唯一日期时间是当前时间,timezone.utcnow()自动执行正确的操作。
默认时区
默认时区是由<cite>[core]</cite>下的<cite>default_timezone</cite>设置定义的时区。 如果您刚刚安装了Airflow,它将被设置为<cite>utc</cite> ,这是推荐的。 您还可以将其设置为<cite>系统</cite>或IANA时区(例如“欧洲/阿姆斯特丹”)。 DAG也在Airflow工作人员上进行评估,因此确保所有Airflow节点上的此设置相同非常重要。
[ core ]
default_timezone = utc
时区感知DAG
创建时区感知DAG非常简单。 只需确保提供时区感知<cite>start_date</cite> 。 建议使用<cite>摆锤</cite> ,但也可以使用<cite>pytz</cite> (手动安装)。
import pendulum
local_tz = pendulum . timezone ( "Europe/Amsterdam" )
default_args = dict (
start_date = datetime ( 2016 , 1 , 1 , tzinfo = local_tz ),
owner = 'Airflow'
)
dag = DAG ( 'my_tz_dag' , default_args = default_args )
op = DummyOperator ( task_id = 'dummy' , dag = dag )
print ( dag . timezone ) # <Timezone [Europe/Amsterdam]>
模板
Airflow在模板中返回时区感知日期时间,但不会将它们转换为本地时间,因此它们保持UTC。 由DAG来处理这个问题。
import pendulum
local_tz = pendulum . timezone ( "Europe/Amsterdam" )
local_tz . convert ( execution_date )
Cron安排
如果您设置了cron计划,Airflow会假定您始终希望在同一时间运行。 然后它将忽略日光节省时间。 因此,如果您有一个时间表,表示每天在格林威治标准时间08:00 + 1的间隔结束时运行,它将始终在08:00格林尼治标准时间+ 1的间隔结束时运行,无论日间节电时间是否到位。
时间增量
对于具有时间增量的计划,Airflow假定您始终希望以指定的间隔运行。 因此,如果您指定timedelta(hours = 2),您将始终希望运行数小时。 在这种情况下,将考虑日光节省时间。