[譯] Robinhood 爲何使用 Airflow

Robinhood 經過定時做業批處理大量任務。這些做業涵蓋了從數據分析和指標彙總到經紀業務如股息支付的範圍。咱們起初使用 cron 來調度這些工做,但隨着它們的數量和複雜性的增長,這愈來愈具備挑戰性:html

  • 依賴管理難。使用 cron,咱們得用上游做業的最壞預期時長來安排下游做業。隨着這些做業的複雜度及其依賴關係的成規模增長,這愈來愈難。
  • 失敗處理和警報必須由做業管理。在存在依賴關係的狀況下,若是做業不能處理重試和上游故障,就只能靠工程師隨叫隨到。
  • 回溯難。咱們得篩查日誌或警報來檢查做業在過去某一天的表現。

爲了知足調度需求,咱們決定放棄 cron,將其替換爲能解決上述問題的東西。咱們調研了一些開源替代品,如 PinballAzkaban 以及 Luigi,最終決定用 Airflow前端

Pinball

Pinball 由 Pinterest 開發,具備分佈式、可水平擴展的工做流管理和調度系統的許多功能。它解決了上面提到的不少問題,但文檔不多,社區相對較小。python

Azkaban

由 LinkedIn 開發的 Azkaban 多是咱們考慮過的替代品中最古老的。它使用屬性文件來定義工做流,而大多數新的替代方案使用代碼。這使得定義複雜工做流程變得更加困難。android

Luigi

由 Spotify 開發的 Luigi 擁有一個活躍的社區,可能在咱們的調研中最接近 Airflow。它使用 Python 來定義工做流,並帶有一個簡單的 UI。可是 Luigi 沒有調度程序,用戶仍然須要依賴 cron 來安排做業。ios

你好,Airflow!

由 Airbnb 開發的 Airflow 擁有一個持續增加的社區,彷佛是最適合咱們目的的。它是一個可水平擴展的分佈式工做流管理系統,容許咱們使用 Python 代碼指定複雜的工做流。git

依賴管理

Airflow 使用操做符做爲定義任務的基本抽象單元,並使用 DAG(有向無環圖)經過一組操做符定義工做流。操做符是可擴展的,這使得自定義工做流變得容易。操做符分爲3種類型:github

  • 動做執行某些操做的操做符,例如執行 Python 函數或提交 Spark Job。
  • 轉移在系統之間移動數據的操做符,例如從 Hive 到 Mysql 或從 S3 到 Hive。
  • 傳感器在知足特定條件時觸發依賴網中的下游任務,例如在下游使用以前檢查 S3 上的某個文件是否可用。傳感器是 Airflow 的強大功能,使咱們可以建立複雜的工做流程並輕鬆管理其前提條件。

下面是一個示例,說明不一樣類型的傳感器如何用於典型的 ETL(數據提取轉換與加載)工做流程。該示例使用傳感器操做符等待數據可用,並使用轉移操做符將數據移動到所需位置。而後將動做操做符用於轉換階段,而後使用轉移操做符加載結果。最後,咱們使用傳感器操做符來驗證結果是否已正確存儲。sql

| 傳感器 -> 轉移 -> | 動做 | -> 轉移 -> 傳感器 |
|      提取        |  轉換 |      加載       |
複製代碼

使用不一樣類型的 Airflow 操做符的 ETL 工做流程apache

故障處理和監控

Airflow 容許咱們爲單個任務配置重試策略配置,並可設置在出現故障、重試以及運行的任務長於預期的狀況下告警。Airflow 有直觀的 UI,帶有一些用於監控和管理做業的強大工具。它提供了做業的歷史視圖和控制做業狀態的工具 —— 例如,終止正在運行的做業或手動從新運行做業。 Airflow 的一個獨特功能是可以使用做業數據建立圖表。這使咱們可以構建自定義可視化以緊密監視做業,並在排查做業和調度問題時充當一個很好的調試工具。後端

可擴展

Airflow 操做符是使用 Python 類定義的。這使得經過擴展示有操做符來定義自定義、可重用的工做流很是容易。咱們在內部構建了一大套自定義操做符,其中一些值得注意的例子是 OpsGenieOperator,DjangoCommandOperator 和 KafkaLagSensor。

更智能的 Cron

Airflow DAG 是使用 Python 代碼定義的。這使咱們可以定義比 cron 更復雜的調度。例如,咱們的一些 DAG 只需在交易日運行。而若是用簡陋的 cron,咱們得設置在全部的工做日運行,而後在應用程序中處理市場假期的狀況。

咱們還使用 Airflow 傳感器在市場收盤後當即開始做業,即便當天只有半天開盤。如下示例經過爲須要複雜的調度的工做流自定義操做符,來在給定日期根據市場時間動態更新。

在給定日期根據市場時間動態調度的工做流

回填

咱們使用 Airflow 進行指標聚合和批量處理數據。隨着需求的不斷變化,咱們有時須要回頭更改咱們彙總某些指標或添加新指標的方式。這須要能往過去任意時間段回填數據。 Airflow 提供了一個命令行工具,讓咱們能使用單個命令跨任意時間段進行回填,也能夠從 UI 觸發回填。咱們使用 Celery(由咱們的 Ask Solem 製做)往 worker box 中分發這些任務。 Celery 的分發能力使咱們可以在運行回填時使用更多 worker box,從而使回填變得快捷方便。

常見的陷阱和弱點

咱們目前使用的是 Airflow 1.7.1.3,它在生產中運行良好,但有本身的弱點和陷阱

  • 時區問題 —— Airflow 依賴系統時區(而不是 UTC)進行調度。這要求整個 Airflow 設置在同一時區運行。
  • 調度程序分開運行預約做業和回填做業。這可能會致使奇怪的結果,例如回填不符合 DAG 的 max_active_runs 配置。
  • Airflow 主要用於數據批處理,於是其設計師決定老是先等待一個間隔後再開始做業。所以,對一個計劃在天天午夜運行的做業,其上下文中傳入的執行時間爲「2016-12-31 00:00:00」,但實際卻在「2017-01-01 00:00:00」才真正運行。這可能會讓人感到困惑,尤爲是在不按期運行的做業中。
  • 意外的回填 —— 默認狀況下,Airflow 會在 DAG 從暫停中恢復時或在添加一個 start_date 爲過去時間的新 DAG 時嘗試回填錯過的任務。雖然這種行爲是可預料的,但終究沒有辦法繞過,若是一個做業不該該回填,這就會致使問題。Airflow 1.8 引入了最近操做符 來解決這個問題。

總結

Airflow 迅速發展成了咱們 Robinhood 基礎設施的重要組成部分。使用 Python 代碼和可擴展 API 定義 DAG 的能力使 Airflow 成爲可配置且功能強大的工具。但願這篇文章對於任何探索調度和工做流管理工具以知足其自身需求的人都頗有用。咱們很樂意回答任何問題。若是這種東西對你頗有意思,考慮下咱們的招聘

感謝 Arpan ShahAravind Gottipati,和 Jack Randall

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索