深入大數(shù)據(jù)平臺心臟:餓了么調度系統(tǒng)全解
隨著餓了么在大數(shù)據(jù)應用的不斷深入,需要解決任務數(shù)量增長快、任務多樣化、任務關系復雜、任務執(zhí)行效率低及任務失敗不可控等問題。
餓了么大數(shù)據(jù)平臺現(xiàn)狀:每天完成大數(shù)據(jù)任務計算 54000+;節(jié)點集群 85 臺。
開源解決方案
Ooize
Ooize 基于工作流調度引擎,是雅虎的開源項目,屬于 Java Web 應用程序。由 Oozie Client 和 Oozie Server 兩個組件構成。
Oozie Server 運行于 Java Servlet 容器(Tomcat)中的 Web 程序。工作流必須是一個有向無環(huán)圖,實際上 Oozie 就相當于 Hadoop 的一個客戶端。
當用戶需要執(zhí)行多個關聯(lián)的 MR 任務時,只需要將 MR 執(zhí)行順序寫入 workflow.xml,然后使用 Oozie 提交本次任務,Oozie 會托管此任務流。
AzKaban
AzKaban 是一套簡單的任務調度服務,是 Linkedin 的開源項目,開發(fā)語言為 Java,包括 Web Server、DB Server、Executor Server。
它用于在一個工作流內以一個特定的順序運行一組工作和流程,定義了一種 KV 文件格式來建立任務之間的依賴關系,并提供一個易于使用的 Web 用戶界面維護和跟蹤你的工作流。
AirFlow
AirFlow 是一個編排、調度和監(jiān)控 Workflow 的平臺,由 Airbnb 開源,現(xiàn)在在 Apache Software Foundation 孵化。
AirFlow 將 Workflow 編排為 tasks 組成的 DAGs,調度器在一組 Workers 上按照指定的依賴關系執(zhí)行 tasks。
同時,AirFlow 提供了豐富的命令行工具和簡單易用的用戶界面以便用戶查看和操作,并且 AirFlow 提供了監(jiān)控和報警系統(tǒng)。
餓了么調度系統(tǒng)特性
餓了么調度系統(tǒng)特性如下:
- 任務創(chuàng)建簡單,執(zhí)行頻率支持 cron 表達式。
- 任務拆分為多種任務類型,支持 19 種任務類型(計算、推送、抽取、檢測)。
- 任務依賴配置簡單,支持不同周期匹配,提供推薦依賴,DAG VIEW 功能。
- 調度與執(zhí)行支持 HA,平滑發(fā)布,宕機恢復,負載均衡,監(jiān)控告警,故障排查,快速擴容,資源隔離。
支持任務類型:
- 計算:Hive、Spark、PySpark、MR、Kylin。
- 推送:MySQL 推送、HBase 推送、Redis 推送、Cassandra 推送、HiveToX 推送、MySQL 多推。
- 抽取:數(shù)據(jù)抽取。
- 檢測:Dal-slave 檢測、數(shù)據(jù)質量檢測、Edsink 檢測、抽取數(shù)據(jù)檢測、數(shù)據(jù)有效期、導入導出校驗。
- 其他:郵件定時任務。
餓了么調度系統(tǒng)整體架構
餓了么調度系統(tǒng)整體架構包括如下 5 個部分:
- Web 服務:主要提供任務創(chuàng)建、實例管理、任務依賴管理、Worker 控制、任務監(jiān)控告警等。
- 調度執(zhí)行:主要由主備 Scheduler 和多個 Worker 節(jié)點組成,負責任務的調度與執(zhí)行。
- 基礎服務:提供了 Eless 自助發(fā)布,ELK 故障排查,Huskar 配置中心,Etrace 埋點監(jiān)控,DOG 告警等功能。
- 底層服務:提供 Hive、Spark、Presto、Kylin、Hadoop 支持。
- 公共設施:包括 MySQL、Redis、Zookeeper。
任務運行過程如上圖:
- Web Service 提供的 API 創(chuàng)建任務和依賴關系,將任務信息存入 MySQL。
- Scheduler 定時生成第二天所有任務實例,并定時輪詢檢查并改變任務狀態(tài)為 Ready(是否到了執(zhí)行時間,是否依賴已完成)。
- Worker 啟動時注冊信息至 Zookeeper,并定時上報機器狀態(tài)給 Scheduler。
- Scheduler 的 ZkWorkerManager 監(jiān)聽 Zookeeper,獲取 Worker 的注冊信息。
- 獲取 Ready 的任務,TaskPacketFactory 將任務構造成 TaskPacket,使用對應的 SubmitPolicy 投遞任務給 Worker。
- Worker 通過 Thrift 接收任務,將任務解析成 InterpreterContext,交給對應的 Interpreter 執(zhí)行,最終由 Docker 運行任務。
- Docker 執(zhí)行情況返回給 Worker,Worker 回調給 Scheduler 將狀態(tài)寫入 MySQL。
餓了么調度系統(tǒng)功能
任務依賴
任務依賴通過如下兩種方式配置:
推薦依賴:是通過任務執(zhí)行完將表和列的信息存入 MySQL,由餓了么血緣系統(tǒng)根據(jù)表的關聯(lián)進行推薦。
手動依賴:則是人為通過界面設置表的依賴關系。依賴關系支持不同周期的任務依賴,偏移量支持表達式【,】【~】。
失敗快速自動重試
當任務執(zhí)行失敗時,系統(tǒng)自動重新調起,默認重試 3 次;當任務投遞過程中,節(jié)點因資源緊張拒絕投遞,調度會根據(jù)負載均衡策略嘗試投遞另一臺機器。
自助故障排查
任務執(zhí)行錯誤故障排查:節(jié)點提供 HTTP 服務,將任務執(zhí)行的日志通過 HTTP 返回給 Web Service 并展示到界面上,提供用戶自助排查。或者通過頁面上的連接訪問餓了么錯誤分析平臺(Grace)自動分析。
任務非執(zhí)行錯誤排查:任務調度和執(zhí)行通過 Flume 將任務日志進行收集,通過在 ELK 上搜索全局 ID 即可查看調度和執(zhí)行情況。
監(jiān)控告警
任務監(jiān)控告警:根據(jù)用戶設置的告警規(guī)則和告警頻率,對任務執(zhí)行超過完成時間和失敗的進行手機、郵件、釘釘告警。
故障監(jiān)控和告警:調度和執(zhí)行節(jié)點進行 Etrace 埋點,通過對接收、執(zhí)行、回調等關鍵點進行監(jiān)測,當指標低于其他節(jié)點時間窗口平均值時,進行告警。
調度&執(zhí)行
調度主備自動切換
調度器通過向 Zookeeper 注冊,并隨機選舉出 Leader 提供調度服務。非 Leader 服務監(jiān)聽 Leader 狀態(tài)并 Wait,當 Leader 出現(xiàn)故障,立即切換為 Leader 角色提供服務。
宕機恢復、自我修復
當所有調度都宕機時,調度服務未恢復期間,Worker 執(zhí)行節(jié)點回調會出現(xiàn)異常。
此時任務狀態(tài)會存入本地文件數(shù)據(jù)庫,并定時重試回調。當調度服務恢復時,任務狀態(tài)恢復正常。
當 Worker 執(zhí)行節(jié)點宕機時,節(jié)點上的任務會處于運行中。當節(jié)點重啟時,Worker 會自我修復運行中的任務,將節(jié)點上未調起的任務重新調起,已經(jīng)運行中的任務通過讀取 Docker 執(zhí)行完寫入本地的狀態(tài)文件進行恢復。
平滑發(fā)布
當 Worker 節(jié)點進行版本升級時,運行中的任務進行自我修復,同上。
資源隔離和快速擴容
通過 Docker 限制每個任務的 Memory 和 CPU 資源使用;將依賴的底層服務打包成鏡像,擴容時便可以很方便的構建需要的環(huán)境。
節(jié)點故障維護
當節(jié)點發(fā)生故障或需要維護時,Worker 執(zhí)行節(jié)點通過 Web 界面即可進行上線下線服務,下線后認為不再接收任務,但不影響節(jié)點上運行中的任務運行。
曾國欽,餓了么大數(shù)據(jù)平臺資深研發(fā),目前負責餓了么大數(shù)據(jù)平臺調度架構設計、架構重構、方案落地等工作。擁有多年的項目研發(fā)和架構經(jīng)驗,曾是微盟支付結算分布式系統(tǒng)架構改造落地的推動者。