Apache Airflow十條最佳實踐

banq發表於2022-02-27

Apache Airflow專案有點像“超級 cron”,因此執行作業的方式與框架本身高度耦合。今天,您必須克服的最大挑戰仍然是排程和作業之間的耦合。

您可以僅根據要執行的 dag 和任務的數量來擴充套件您的 Airflow 部署

 

1)Airflow是一個編排框架,而不是一個執行框架:

對於您的工作,您應該只使用在單獨的處理解決方案中觸發 Airflow 計算的運算子,例如:

  • 一個容器:K8S、GKE、EKS、ECS、Cloud RUN……
  • 無伺服器函式:AWS Lambda、雲函式
  • spark worker:EMR、DATAPROC …
  • 一個查詢:BigQuery、Redshift……

在 Airflow 中直接執行您的作業(執行大量 CPU、記憶體或 IO 操作)會給您的 airflow_workers 帶來壓力。Airflow 應該只執行操作員啟動和斷言在單獨的處理解決方案中執行的任務。

 

2) 避免使用 PythonOperator 進行工作:

如果您使用 PythonOperator 則只執行非常非常簡單的程式碼,它必須只執行簡單的 IO 操作(如轉換小型 XCOM),否則使用規則 1 的運算子執行您的作業。

不要使用 VirtualVenvOperator 或 BashOperator 或 DockerOperator(除非您在 Airflow 工作人員的另一臺主機上觸發執行),您應該使用 KubernetesPodOperator 、 EmrCreateJobFlowOperator 之類的運算子……

 

3)在建立之前檢查現有的operators:

在 99% 的情況下,您不應該建立新的 Airflow operator,請仔細檢視現有operator。檢查您嘗試執行的操作是否可以與現有operator的組合(例如,第一個任務是 SubmitXXOperator,第二個任務是 SensorXXOperator)

如果你真的覺得需要一個新的operator,請在 GitHub 或 slack 上詢問 Airflow 社群,在大多數情況下,他們會向你展示現有operator的方法。

如果您絕對需要自定義現有的運算子,擴充套件現有的類,不要從零開始重新建立所有內容。

在我目前的公司中,我們只建立了 2 個operator

 

4) 不要在您的 Airflow 部署中安裝任何自定義依賴項:

唯一允許的依賴項是 Airflow 社群支援的提供程式apache-airflow-providers-XXX

喜歡 :

- apache-airflow-providers-cncf-kubernetes- apache-airflow-providers-google- apache-airflow-providers-slack

因為這些是 Airflow 社群確保與 Airflow 本身具有良好相容性的唯一軟體包。安裝任何其他依賴項將使部署處於危險狀態,並可能在升級時導致依賴地獄。

我不建議安裝不屬於官方列表的自定義 Airflow 提供程式:

  • - https://pypi.org/project/airflow-dbt/
  • - https://github.com/great-expectations/airflow-provider-great-expectations

  

5)Airflow不是一個資料lineage的解決方案。

Airflow是一個執行在operator中定義的任務的排程器,目前Airflow確實有非常有限的(測試版)lineage功能。這些功能允許Airflow與使用Open Lineage標準的第三方解決方案(如Marquez)整合。

你應該絕對避免重新實現一個自定義/自制的解決方案,無論多麼誘人。

 

6)Airflow不是一個資料儲存解決方案。

Airflow operator可以返回資料,Airflow將把這些資料儲存在其內部資料庫airflow_db中(由傳統的RDBS支援,如Postgresql)。我們稱儲存在airflow_db中的資料為XCOM。

但是,airflow_db不應該儲存自定義資料,而只應該儲存非常小的後設資料(比如我們的BigQueryToXCOMOperator通常會返回一個單一的值,如時間戳)。

最好的做法是不從operator那裡返回資料。如果你有一個特殊的情況,operator必須返回資料(像一個複雜的json的多行),你需要使用一個自定義的xcom_backend來寫入資料,而不是在airflow_db,而是在另一個地方(如S3或GCS)。

你的自定義xcom_backend必須只用於你明確選擇的任務(注意,預設情況下,一個xcom_backend將被Airflow用於所有XCOM)。

在所有情況下,如果你用外部處理方案(如KubernetesPodOperator)執行一個作業,那麼該作業負責將結果寫入儲存(如S3、GCS),其路徑取決於排程器提供的上下文。

 

7)不要把安全金鑰放在Airflow的變數或連線中。

Airflow可以儲存DAG可以通過模板訪問的變數,因此DAG在執行時總是會檢索到該變數的最新版本,對於連線也是如此。

但是,如果一個變數或連線儲存了一個金鑰(如私鑰),不要直接在Airflow中註冊這個變數或連線,你必須在一個金鑰儲存(Vault、GCP祕密管理器...)中註冊該變數或連線,並在Airflow中使用一個金鑰後臺。

你的自定義secret_backend必須只檢索你定義的變數或連線(注意,預設情況下,Airflow會首先嚐試為自定義secret_backend中的所有變數和連線找到祕密,並對正常的Airflow變數或連線發出警告日誌)。

  

8)你的作業必須最大限度地不受排程的影響。

如果你重新執行一個作業,它必須是empotent的,而且你還必須有能力在Airflow之外執行你的作業。

例如:如果你有一個抓取API並將結果寫入S3的小作業,你必須能夠在你電腦上的容器中執行該作業,因為該作業從env_vars或args中獲取所有的上下文。這確保了實際計算與Airflow的完全解耦(排程器和任務實現之間的界限清晰)。

一個好的做法是,在一個獨立的倉庫中編碼你的作業,而不是你的dags(因為dags只需要知道實現作業的容器的名稱和版本)。

然後在作業庫中:為每個作業關聯一個小的docker-compose,以便能夠在一個固定的環境中執行該作業。

 

9) 不要把Airflow的不同元素部署在一起。

如果你在K8S中用官方的HELM檔案部署Airflow,這是預設行為。

但是,如果你選擇手動部署,那麼你必須隔離airflow_scheduler、airflow_webserver和airflow_workers,這樣你就可以根據你的用例來擴充套件它們。

 

10) LocalExecutor和KubernetesExecutor並不容易。

LocalExecutor只具有縱向擴充套件性,因為你將在與排程器相同的位置執行任務(擁有多個排程器的HA並不意味著你應該擁有N個排程器來橫向擴充套件你的Airflow堆疊)。因此,對於生產環境來說,不建議使用這種方法。

KubernetesExecutor將直接使用Kubernetes,這意味著你將把壓力直接放在K8S叢集上(每個任務都有一個新的pod),使用該執行器更難檢測和解決擴充套件的問題。

CeleryExecutor比KubernetesExecutor更容易理解和操作,而且用該執行器可以消除Airflow和K8S之間的耦合。

 

相關文章