Airflow 基礎系列 - 02 (Executor詳解)

語言: CN / TW / HK

本文引自https://www.astronomer.io/guides/airflow-executors-explained

對於是一個Airflow新手而言,Airflow Executor的概念可能會難以理解。即使作為成熟的Airflow使用者和資料工程師,想要確定在實踐中使用哪種Executor,也需要慎重的權衡各種因素。

為了讓讀者更好的理解Airflow Executor,本文將從以下2個方面進行闡述:

  • 介紹Executor的核心功能,在Airflow架構中的地位和一些重要配置引數

  • 介紹3種最常用的Executor: LocalExecutor,CeleryExecutor和KubernetesExecutor

什麼是Executor

概念上來說,Executor代表了Airflow任務例項的執行機制。當一個DAG完成建立並觸發一次DAG Run之後,為了確保該DAG中的各個task按期望的順序正確執行,Airflow會執行以下步驟:

  1. DAG中的所有task資訊和依賴關係會儲存在Airflow配置的元資料庫中(可能是MySQL或者PostgreSQL)。

  2. Scheduler會讀取元資料庫中的任務,根據DAG定義決定task執行順序生成並啟動執行計劃,將task例項新增到排程佇列中

  3. Executor(從架構圖上可以看到部署在Scheduler服務中)接收排程佇列中的task例項,確認完成這個task例項需要哪些資源,並將task例項分發到指定資源上執行。

如上所述,對於不同Executor之間的區別,我們可以總結為用於執行task例項資源的區別。這種例項資源可以是分散式的(如Celery,Yarn或Kubernetes),也可以是本地化的(Local)。

常用的Executor

下面我們將著重介紹3種常用的Executor和他們的主要使用場景。

LocalExecutor

在Airflow中使用LocalExecutor是比較典型的單節點部署架構,Scheduler和所有執行Task的程式碼都執行在同一個節點上(可能是你的膝上型電腦或者一個EC2例項)。Airflow Worker以LocalWorker的形式 併發 執行Scheduler分發的task。

在使用LocalExecutor的情況下,我們不需要該節點外的其他資源即可執行DAG。由於LocalExecutor將所有工作負載都執行在一個節點上。其優缺點如下所述

優點

  • 易於理解和部署

  • 即使在單節點上依然具有併發能力

缺點

  • 缺乏擴充套件性

  • 存在單點失敗可能性

基於以上特性,在測試或者開發環境下選擇LocalExecutor是一個理想的選擇。在生產環境下,考慮到系統魯棒性和擴充套件性應該避免使用LocalExecutor。

CeleryExecutor

CeleryExecutor是一種易於水平擴充套件的Executor,基於Celery實現。Celery本身是一個Python分散式佇列元件,在這裡我們不對Celery相關的技術細節贅述,詳情可參考 Celery官方文件(https://docs.celeryproject.org/en/stable/) 。CeleryWorker需要和一個Worker節點池(CeleryWorker)通過訊息佇列協同工作,以實現任務排程和執行的靈活性和可用性。假如Worker節點池中的節點宕機,CeleryExecutor能夠通過將任務進行重新分發以實現故障恢復。

需要注意的是,使用CeleryExecutor時必須要部署一個訊息佇列中介軟體(例如RabbitMQ/Redis)才能使整個流程順利工作。對於如何選擇合適的訊息佇列中介軟體,也可以參考Celery官方文件中的相關介紹(https://docs.celeryproject.org/en/stable/getting-started/backends-and-brokers/index.html)。

總結來說,CeleryExecutor相較於LocalExecutor,在高可用性和水平擴充套件性上具有顯著優勢,是一種比較適合於生產環境部署的選擇。但是由於使用CeleryExecutor時需要額外引入訊息佇列中介軟體,也會為系統的整體運維帶來額外的成本。

KubernetesExecutor

KubernetesExecutor利用Kubernetes在資源管理、排程等領域的能力,實現Airflow任務例項的分發。關於Kubernetes相關的知識我們在此同樣不做贅述,詳情可參考Kubernetes 官方文件(https://kubernetes.io/)

KubernetesExecutor通過 Kubernetes API啟動pods以觸發Airflow任務例項的執行,因此在使用時至少需要指定pod的資源用量(CPU/Memory),Service Account和執行映象。由於 Kubernetes 具備較強的伸縮能力,在任務數量差別較大的時間段,我們可以通過動態擴縮容最大程度的實現資源的有效利用。

在使用Local和Celery兩種Executor時,定期輪詢檢查每個task的狀態(是running, queued還是failed)的工作由Scheduler獨自承擔。而在使用KubernetesExecutor時,而Scheduler僅僅需要藉助Kubernetes的Watcher API訂閱pods的事件日誌,即可在任務例項失敗時更新其狀態,避免了大量的無效輪詢操作。這樣做在某些場景下可以有效降低Scheduler的工作負載。

綜上所述,相比於Local和Celery兩種Executor,KubernetesExecutor在資源利用、容錯和任務精細化配置等方面,因依託於Kubernetes的強大能力而有著較大的優勢。當然選擇KubernetesExecutor也意味著運維人員需要在Kubernetes的知識儲備上有較深的積累,存在一定的使用門檻。