時區

預設啟用時區支援。Airflow 在內部和資料庫中以 UTC 格式儲存日期時間資訊。它允許您使用依時區而定的排程來執行 DAG。目前,Airflow 不會在使用者介面中將它們轉換為終端使用者的時區。它在該處將永遠以 UTC 顯示。此外,運算子中使用的範本也不會轉換。時區資訊會公開,是否處理取決於 DAG 的撰寫者。

如果您的使用者位於多個時區,並且您想要根據每位使用者的實際時間顯示日期時間資訊,這會很方便。

即使您只在一個時區中執行 Airflow,將資料以 UTC 格式儲存在資料庫中仍然是良好的實務 (在 Airflow 變得時區感知之前,這也是建議甚至要求的設定)。主要原因是許多國家/地區使用日光節約時間 (DST),時鐘在春季向前撥,在秋季向後撥。如果您使用當地時間,您很可能在轉換發生時一年會遇到兩次錯誤。(pendulum 和 pytz 文件更詳細地討論了這些問題。) 這對於簡單的 DAG 可能沒關係,但如果您在金融服務業等有每日截止期限要趕上的情況下,這就會是個問題。

時區在 airflow.cfg 中設定。預設情況下,它設定為 UTC,但您可以變更它以使用系統設定或任意 IANA 時區,例如 Europe/Amsterdam。它取決於 pendulum,它比 pytz 更準確。當您安裝 Airflow 時,Pendulum 會一併安裝。

注意

Pendulum 預設依賴其自己的時區資料庫,該資料庫的更新頻率不如 IANA 資料庫。您可以透過將 PYTZDATA_TZDATADIR 環境變數設定為系統的資料庫,例如 /usr/share/zoneinfo,來讓 Pendulum 依賴系統的資料庫。

Web UI

預設情況下,Web UI 將以 UTC 顯示時間。可以透過使用右上角的選單 (按一下時鐘以啟用它) 來變更顯示的時區

../_images/ui-timezone-chooser.png

「本地」是從瀏覽器的時區偵測到的。「伺服器」值來自 [core] 區段中的 default_timezone 設定。

使用者選取的時區儲存在 LocalStorage 中,因此是每個瀏覽器的設定。

注意

如果您已將 Airflow 安裝設定為使用不同的預設時區,並希望 UI 使用相同的時區,請將 [webserver] 區段中的 default_ui_timezone 設定為空字串或相同的值。

(目前預設為 UTC,以保持 UI 在點發布之間預設行為的一致性。)

概念

Naive 與 aware datetime 物件

Python 的 datetime.datetime 物件具有 tzinfo 屬性,可用於儲存時區資訊,表示為 datetime.tzinfo 子類別的實例。當此屬性設定並描述偏移量時,datetime 物件是 aware 的。否則,它是 naive 的。

您可以使用 timezone.is_localized()timezone.is_naive() 來判斷 datetime 是 aware 還是 naive。

由於 Airflow 使用時區感知 datetime 物件。如果您的程式碼建立 datetime 物件,它們也需要是 aware 的。

from airflow.utils import timezone

now = timezone.utcnow()
a_date = timezone.datetime(2017, 1, 1)

Naive datetime 物件的解讀

雖然 Airflow 完全以時區感知方式運作,但它仍然接受 DAG 定義中 start_datesend_dates 的 naive 日期時間物件。這主要是為了保持向後相容性。如果遇到 naive 的 start_dateend_date,則會套用預設時區。套用的方式是假設 naive 日期時間已在預設時區中。換句話說,如果您將預設時區設定為 Europe/Amsterdam 並建立 naive datetime start_datedatetime(2017, 1, 1),則會假設它是 2017 年 1 月 1 日阿姆斯特丹時間的 start_date

dag = DAG(
    "my_dag",
    start_date=pendulum.datetime(2017, 1, 1, tz="UTC"),
    default_args={"retries": 3},
)
op = BashOperator(task_id="hello_world", bash_command="Hello World!", dag=dag)
print(op.retries)  # 3

不幸的是,在 DST 轉換期間,某些日期時間不存在或不明確。在這種情況下,pendulum 會引發例外。這就是為什麼當啟用時區支援時,您應該始終建立 aware datetime 物件的原因。

實際上,這很少是問題。Airflow 在模型和 DAG 中為您提供時區感知 datetime 物件,而且大多數時候,新的 datetime 物件是透過 timedelta 算術從現有物件建立的。應用程式程式碼中經常建立的唯一 datetime 是目前時間,而 timezone.utcnow() 會自動執行正確的操作。

預設時區

預設時區是由 [core] 下的 default_timezone 設定定義的時區。如果您剛安裝 Airflow,它將設定為建議的 utc。您也可以將其設定為 system 或 IANA 時區 (例如 Europe/Amsterdam)。DAG 也會在 Airflow worker 上評估,因此務必確保所有 Airflow 節點上的此設定都相同。

[core]
default_timezone = utc

注意

如需設定組態的詳細資訊,請參閱 設定組態選項

時區感知 DAG

建立時區感知 DAG 非常簡單。只需確保使用 pendulum 提供時區感知的 start_date 即可。請勿嘗試使用標準函式庫 timezone,因為已知它們有局限性,並且我們刻意不允許在 DAG 中使用它們。

import pendulum

dag = DAG("my_tz_dag", start_date=pendulum.datetime(2016, 1, 1, tz="Europe/Amsterdam"))
op = EmptyOperator(task_id="empty", dag=dag)
print(dag.timezone)  # <Timezone [Europe/Amsterdam]>

請注意,雖然可以為任務設定 start_dateend_date,但 DAG 時區或全域時區 (依該順序) 將始終用於計算資料間隔。首次遇到時,開始日期或結束日期將使用與 start_dateend_date 相關聯的時區轉換為 UTC,然後在計算時將忽略此時區資訊。

注意

在撰寫時區感知 DAG 時,您必須確保底層時區函式庫 (例如:pendulum) 已使用法規的最新變更 (日光節約變更等) 進行更新…。當預期時間變更時,您應使用底層時區函式庫驗證切換是否會如預期發生。可能需要更新函式庫版本。作為一般建議,如果可以 UTC 撰寫 DAG,則最好。

範本

Airflow 在範本中傳回時區感知日期時間,但不會將它們轉換為當地時間,因此它們仍為 UTC。這留給 DAG 處理。

import pendulum

local_tz = pendulum.timezone("Europe/Amsterdam")
local_tz.convert(logical_date)

Cron 排程

使用 cron 排程的時區感知 DAG 尊重日光節約時間。例如,在 US/Eastern 時區中,開始日期為 0 0 * * * 的 DAG 將在日光節約時間期間每天在 UTC 時間 04:00 執行,否則在 05:00 執行。

時間差

對於開始日期,使用 timedeltarelativedelta 排程的時區感知 DAG 尊重日光節約時間,但在排程後續執行時不會針對日光節約時間進行調整。例如,開始日期為 pendulum.datetime(2020, 1, 1, tz="UTC") 且排程間隔為 timedelta(days=1) 的 DAG 將每天在 UTC 時間 05:00 執行,而與日光節約時間無關。

此條目是否有幫助?