Uber是如何管理大規模數據工作流的?

讓這些數據可操作,需要進行數據提取、轉換、解析和編排,從而在傳統商業智能、機器學習、模型訓練、可視化和報表等場景中廣泛應用。儘管在Uber迅速發展的初期,上線了廣覆蓋面的數據工作流系統,用戶須針對每種用例選擇幾種工具疊加使用。儘管此大型工具箱可實現敏捷且響應迅速的增長,但事實證明,它難以管理和維護,需要工程師在應對不同項目時,學習重複數據工作流系統。因此,Uber需要一個可以創建、管理、調度和部署數據工作流的中央工具。

利用Uber之前部署的各種工具,包括基於Airflow的平臺,Uber的技術開始開發與Uber規模相稱的系統。這項工作使Uber開發了集中式工作流管理系統Piper,該系統使Uber的數據工作流大衆化,並使從城市運營團隊到機器學習工程師的每個人都能更快速、更高效地開展工作。

 

統一工作流管理系統之路

 

直到幾年前,Uber的團隊使用了多個數據工作流系統,其中一些基於開源項目,如Apache Oozie、Apache Airflow和Jenkins,也有一些用Python和Clojure編寫的定製解決方案。每個需要移動數據的用戶都必須學習和選擇使用不同的系統,這取決於他們需要完成的特定任務。每個系統都需要根據額外的維護和操作工作來保持其運行、排除問題、修復Bug以及教育用戶。

經過一番思考,Uber決定聚集到單個工作流程系統上。在評估行業中可用的數據工作流工具以及權衡了每種工具的利弊,並考慮了多個因素,如易用性、穩定性、開源生態系統、對Hadoop生態系統的依賴性、領域專用語言(DSL)的表達能力以及所使用的編程語言(是否與我們的用戶羣的語言技能匹配)之後,Uber研發了新的工作流系統。在新系統中,Uber尋找以下特點:

  • 工作流應該易於通過代碼編寫進行創建,同時也要具有表現力並支持動態生成工作流。

  • 支持工程師習慣的開發流程,包括將數據工作流開發爲代碼,並通過版本修訂控制進行跟蹤。

  • 工作流易於可視化、容易管理。

  • 工作流日誌易於訪問,便於查看工作流的歷史及當前運行狀態。

經過這次評估,並以融合支持Uber數據規模的單個工作流程系統爲目標,Uber選擇了基於Airflow的系統。基於Airflow的DSL提供了靈活性、表現力和易用性的最佳平衡,同時可供包括數據科學家、開發人員、機器學習專家和運營人員在內的廣泛用戶羣體使用。

當Uber朝單一數據多租戶工作流系統發展時,開始停用了原有類似系統的工作。棄用這些系統極大地簡化了用戶工作流的編寫,以及提高團隊管理能力和系統長期改進的能力。

 

選擇部署模型:集中式多租戶平臺

 

在部署系統時,可以選擇採用單一的集中管理安裝,而不是爲公司每個團隊或組織進行安裝。Uber找到了兩個行業內的案例,從單一的亞馬遜AWS數據管道託管安裝到Google Cloud Composer的Airflow分佈式安裝。在後一種情況下,用戶或管理員負責系統的設置和配置,而賣方僅提供有限的支持。

Uber考慮了以下幾個因素,才做出此決定:

  • 引入更改後,系統如何升級?

  • 發生錯誤或基礎結構問題時,誰負責on-call和系統支持?

  • 隨着工作流程數量的增加,誰來負責擴展系統?

  • 對於不同版本的不同配置系統,如何避免雪花式的集羣和節點?

  • 系統是否需要使用它的團隊進行任何維護或配置?

考慮到上述因素後,Uber構建了一個集中部署的模型,即由數據工作流管理團隊支持的每個數據中心進行一次單一安裝。對於終端用戶而言,Piper(在該系統上的實現)是自助且可靠的,但是由Uber的技術團隊對Piper進行管理,以確保其能進行更新並能夠隨着公司工作流程的增長而穩定擴展。還通過功能需求說明,文檔和培訓爲終端用戶提供支持,他們無需瞭解系統的內部工作原理。

在選擇集中部署模型時,因爲需要確保Piper擴展到支持比每個團隊部署時所需的工作流大得多的數量,因此每個團隊部署只需要有限數量的工作流。與多安裝模型相比,Piper還需要提供更好的隔離和多租戶功能。

 

系統架構

 

雖然Piper基於原始的開源Airflow架構,但Uber重構了大多數系統,使其性能更高,可用性更好,並適合Uber的基礎架構。下圖詳細說明了Piper的初始結構體系:

圖1:Piper最初的架構基於Airflow(一個開源的集創建、調度和監控與一體的解決方案)

 

Piper的原始架構包含以下五個組件:

  • Web服務器:爲HTTP請求提供服務的應用程序服務器,包括針對UI端點以及JSON API端點的HTTP請求。

  • 調度程序:負責調度工作流程和任務。調度程序考慮了各種因素,如調度間隔,任務依賴性,觸發規則和重試次數,並使用此信息來計算下一組要運行的任務。一旦資源可用,它將把排隊等待的任務在適當的執行器(即示例中的Celery)中執行。

  • Celery Worker:容器執行所有工作流程任務。每個容器從隊列(即示例中的Redis)中拉取下一個要執行的任務,並在本地執行。(可執行任務由工作流ID、任務ID和執行日期進行標識)。

  • 元數據數據庫:爲系統中所有實體(如工作流、任務、連接、變量和XCOM)記錄真實來源,以及工作流的執行狀態。

  • Python工作流:用戶編寫的Python文件,用於定義工作流、任務和庫。

 

與用戶代碼隔離

 

通過在生產環境操作,Piper吸取的重要教訓是,需要將用戶代碼與系統代碼隔離。工作流DSL的一個優點是,工作流可以由任何任意的Python構造定義,如,循環訪問磁盤上的配置文件,調出外部服務以獲取配置數據或將其在命令行執行。但是,這種靈活性與系統穩定性和可靠性相沖突,因爲用戶代碼可以運行任意邏輯,執行速度慢,並可能導致系統錯誤。通常,良好的系統設計鼓勵儘可能將用戶代碼與系統代碼隔離。如下圖2所示,原始體系結構依賴於在所有系統組件(包括調度程序,Web服務器和Celery worker)中執行用戶代碼。

圖2:用戶代碼在所有系統組件中執行,可能會對Piper的可用性和性能產生負面影響。

 

Piper的目標之一是儘可能可靠、快速地調度任務。但是,用戶代碼在各種組件中運行爲系統穩定性帶來了諸多問題。在Uber的環境中,工作流驅動程序可以爲單個Python文件生成數千個工作流,有時會等待外部服務來檢索配置,且加載速度慢,從而對系統可用性和性能產生負面影響。

基於這些思考,意識到可以將工作流的元數據表示與Python定義解耦。單個工作流定義文件可以分解爲兩個單獨的表示形式:

  1. 工作流和任務的元數據表示:序列化表示,包括工作流/任務屬性以及任務之間的依賴關係圖。此表示可由諸如調度程序和Web服務器之類的系統組件使用,它們僅需要了解有關每個工作流程的高級元數據,而無需加載或執行用戶管道定義文件。

  2. 完全實例化的工作流:用戶提供的完全實例化的Python任務和工作流表示形式,符合DSL規範。因此可以使用此表示形式來提取工作流元數據並在Celery worker中執行任務。

圖3:使用Piper,可以將Pipeline定義視爲兩種表示形式:序列化的元數據表示形式和完全可執行的工作流表示形式。

 

爲了實現元數據分解,在系統中引入了一個新組件,其作用是加載用戶Python工作流程的定義、提取,然後將其序列化的元數據表示形式存儲在數據庫中。元數據表示可以由系統的其他組件(如調度程序和Web服務器)使用,而不必加載任何用戶代碼。在將工作流的元數據表示與可執行表示分離時,能夠將許多系統組件與必須加載Python工作流定義解耦,從而使系統更可靠、性能更高。

圖4:不再需要在調度程序或Web服務器中加載用戶代碼。使用Piper,工作流序列化程序通過從用戶代碼中提取元數據來提供隔離。

 

重構以實現高可用性和水平伸縮彈性

 

通過元數據序列化與用戶代碼隔離之後,Uber希望進一步提高Piper的可伸縮性和系統可用性。Uber的目標是實現:

  • 提高系統效率和語言支持:在Uber,對Go和Java用於微服務的使用進行了標準化,因此,在Piper中也選擇遵循這種語言標準化,並提供較低的調度延遲和性能改進,同時仍將在Python中保留DSL。

  • 高可用性和消除單點故障:Uber在Apache Mesos / μDeploy系統上託管服務,運行在Apache Mesos集羣上的Docker容器內。這些服務必須在不宕機的情況下,妥善處理容器崩潰,重啓和容器重定位。在現有的系統體系結構中,調度是單點故障:如果調度程序節點消失,系統將停止調度任何任務。單點故障也發生在節點重新分配期間,通常由部署,硬件維護或資源短缺引起。

  • 調度的水平可伸縮性:現有系統僅支持在任何時間運行單個調度程序。隨着新工作流的添加,調度延遲往往會隨着時間的推移而增加。我們希望能夠添加額外的調度程序,自動接管部分運行的工作流。這將提供自動故障轉移、減少的調度延遲以及跨多個節點負載均衡作業調度的能力。

爲了實現這些目標,應用了分佈式系統概念來提高Piper的可用性和可伸縮性。引入了使用分佈式協調服務來提供可用於強化系統的原語,並通過以下更改對系統進行重構:

  • 用Java重寫Piper的調度程序和執行程序組件:自發布Piper以來,調度程序和執行程序與加載用戶Python代碼解耦,因此現在可以自由使用最適合此job的任何平臺或工具。隨着Uber在Java和Go上的使用進行標準化,又用Java重寫了調度程序和執行程序組件,從而能夠使用Java性能更高的併發語義來提高系統效率。

  • 利用主要運行程序的選舉:對於要作爲單例運行的任何系統組件,如序列化程序和執行程序,都增加了主要運行程序的選舉功能。如果主要運行程序變得不可用,將從可用的備份節點中自動選出新的主要運行程序。這消除了單點故障,還減少了Apache Mesos中的部署、節點重啓或節點重定向期間的宕機時間。

  • 引入工作分區:回想一下,目標是能夠添加更多調度程序,並將這些調度程序自動分配給一部分工作流程並對其進行調度。使用分佈式協調服務,能夠爲任務調度實現有效的工作分區。這種方法可以隨時向Piper添加新的調度程序。新的調度程序上線後,會自動爲其分配一組工作流,並對工作流進行調度。當調度程序節點聯機或脫機時,工作流集將被自動調整,從而爲任務調度提供了高可用性和水平伸縮性。

圖5:高可用性,解耦和完全分佈式的Piper架構設計,支持多個調度程序同時運行,同時消除單點故障。

 

系統開發完成並進入測試階段後,決定使用部分遷移策略,而不是整體遷移所有工作流。首先並排部署了Python和分佈式Java調度程序,並能夠在工作流級別切換調度模式。通過這種策略,能夠完全遷移所有工作流程,而不會影響終端用戶。通過上述更改,現在已經獲得了所有系統組件的高可用性和工作流調度的水平可伸縮性,並通過Java併發提高了性能。

  

其他平臺增強功能

 

儘管到目前爲止的主題涵蓋了在調度程序和工作流序列化上執行的主要重構,但同時Uber的技術團隊也將一些其他增強功能集成到了平臺,這些增強功能概述如下:

  • 多種數據中心語義:目前在每個數據中心運行一次Piper安裝。添加了工作流語義,用戶可以指定在單計算模式還是雙計算模式下運行工作流。對於數據中心故障,系統自動將工作流轉移到其他數據中心,而無需用戶干預。

  • 多租戶:由於有數萬個用戶和數百個團隊在使用該系統,因此需要使Piper成爲多租戶使用模式。同時 ,還爲工作流、連接和變量之類的許可實體添加了更多語義,以確保對適當所有者的訪問控制。

  • 審計:諸如編輯連接、編輯變量和切換工作流之類的用戶操作將保存到審計存儲中,以便在需要時進行搜索。

  • 回調:已實現了通用的回調功能,該功能使用戶只需在UI界面中通過幾次點擊即可爲任何現有工作流程創建和管理回調。

  • 視覺創作工具:在Uber,有幾類用戶需要創建工作流,其中一些用戶可能不熟悉Python開發。因此,提供了幾種創建工作流的方法,通常是通過領域特定的UI動態創建工作流。這些UI創建工具特定於垂直領域,如機器學習,儀表板和數據提取。目前還在開發通用的可視化拖放工具,用於在系統頂層創建工作流程。

  • 工作流程定義REST API:增加了通過REST API調用動態創建工作流程的功能,而無需使用Python代碼。這類似於Apache Storm Flux API。

  • 持續部署:使用monorepo存儲工作流程定義代碼。確保將monorepo連續部署到必要的系統組件中,而無需用戶干預。

  • 持續集成:每個用戶提交到monorepo的工作流,都需要進行一系列的單元測試,以確保不引入任何錯誤並確保工作流的有效性。

  • 指標和監控:已經使用Uber的M3和uMonitor系統插入了指標和監控。還添加了canary工作流,以評估系統運行狀況和性能,收集有關係統和基礎結構統計信息,並使用這些指標在系統出現故障時發出警報。

  • 日誌記錄:對任務日誌進行了重新設計,以適應Uber日誌記錄基礎架構,並確保它對最終用戶可靠且即時可用,而不會影響系統可用性或可靠性。

     

 

關鍵總結

 

從最初的系統部署到今天,Uber已經從數十個工作流發展爲數以萬計的工作流,這些工作流每天由數萬個用戶管理着成千上萬的任務。在保持系統穩定和性能的同時做到了這一點,並提高了可用性,可伸縮性和易用性。通過遵循以下原則,重構造了系統,以支持Uber不斷擴大的規模:

  • 優先考慮用戶友好性和編寫工作流的表現力。包括輕鬆管理工作流和即時訪問工作流日誌。

  • 儘可能在整個公司範圍內集成到統一的產品。集成到統一的系統中可以大大減少維護負擔,on-call事件以及用戶的困惑,同時可以讓團隊統一圍繞一個產品進行迭代改進。

  • 選擇中央多租戶部署模型。在案例中,使用的模型使之能更好地支持Uber的用戶並提供簡便的升級路徑,而無需團隊在創建系統的新實例時瞭解系統內部結構或配置。

  • 儘可能避免在系統組件中運行用戶代碼。分流工作流元數據極大地提高了我們系統的可靠性,並且還提供了額外的靈活性(允許用Java重寫寫調度組件)。

  • 消除任何單點故障,確保正常運行時間和系統可用性。

  • 使用分佈式系統概念,如主要運行程序選舉、故障轉移和工作分區,以提高可用性和可伸縮性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章