5K項目是飛天平臺的裡程碑,系統在規模、性能和容錯方面都得到了飛躍式的發展,達到世界領先水平。伏羲作為飛天平臺的分布式調度系統,能支持單集群5000節點,並發運行10000作業,30分鐘完成100TB數據Terasort,性能是當時Yahoo!在Sort Benchmark上世界紀錄的兩倍。
「飛天」是阿里巴巴的雲計算平臺,其中的分布式調度系統被命名為「伏羲」(代碼名稱Fuxi),名字來自我國古代神話人物。伏羲主要負責管理集群的機器資源和調度並發的計算任務,目前支持離線數據處理(DAG Job)和在線服務(Service),為上層分布式應用如ODPS/OSS/OTS提供穩定、高效、安全的資源管理和任務調度服務,為阿里巴巴集團打造數據分享第一平臺的目標提供了強大的計算引擎。
伏羲系統設計上採用M/S架構(如圖1所示),系統有一個被稱為「伏羲Master」的集群控制中心,其餘每臺機器上會運行一個叫做「伏羲Agent」的守護進程,守護進程除了管理節點上運行的任務外,還負責收集該節點上的資源使用情況,並將之匯報給控制中心。控制中心與伏羲Agent之間使用心跳機制,以監測節點健康狀態。當用戶向伏羲Master提交一個任務時, 伏羲Master會調度出一個可用節點在其上啟動任務的主控進程AppMaster,主控進程隨後會向伏羲Master提出資源請求,得到伏羲Master分配的資源後,AppMaster通知相應節點上的伏羲Agent運行任務Worker。伏羲是一個支持多任務並發的調度系統,控制中心伏羲Master負責在多個任務之間仲裁,支持優先級、資源Quota配額和搶佔。
圖1 伏羲架構
使用伏羲,用戶可以運行常見的MapReduce任務,還可以託管在線服務,滿足不同應用場景的需求。多用戶可以共享集群,伏羲支持配置分組的資源配額,限定每個用戶組可以使用的計算資源。緊急任務如重要數據報表可以提高任務優先級來優先使用計算資源。
5K帶來的挑戰
在5K項目攻堅過程中,我們看到大型雲計算平臺從設計到實現每一步都可能存在性能「陷阱」,主要有三方面原因:規模放大效應,當系統擴展到數千節點時,原本非瓶頸與規模成正比的環節,其影響會被放大;木桶效應,很多時候,系統99%的地方都被優化過,完成剩下1%的優化看起來只是「錦上添花」,然而那1%很可能就會成為影響系統性能的致命的瓶頸;長路徑模塊依賴,有些請求處理過程可能需要跨越多個模塊(包括外部模塊),而外部模塊性能的不穩定性最終可能會影響這個請求的處理性能和穩定性。
5K項目是一場全方位戰役,給伏羲系統帶來規模、性能、穩定、運維等多方面的技術挑戰,例如下面的性能「陷阱」。
我們做了大量伏羲優化工作來規避上述的性能「陷阱」,涉及到架構設計、實現細節和模塊依賴,透過現象看本質,從最底層性能分析入手一步步找到瓶頸。下面結合具體的實戰例子來分享優化過程。
在5K項目初期階段,我們測試大規模並發作業時發現,當作業數量超過1000時就容易出現運行時間變長的現象。分析監控曲線和日誌,我們發現AppMaster發給伏羲Master的資源請求出現大量消息超時,AppMaster遲遲拿不到資源,資源請求處理的延時很高。
消息從到達伏羲Master進程到最終被處理返回的總時間主要包括在隊列中等待時間和實際處理的時間,因此延時高無非是兩個原因:消息處理本身的OPS下降;消息堆積在待處理隊列中未被及時處理。順著這一思路,在通過Profiling發現伏羲Master資源調度關鍵函數並沒有佔到整個消息處理延時的大部分後,罪魁禍首就只剩下消息堆積了。在繪出了伏羲Master中資源調度消息隊列中消息堆積的曲線之後,果然發現當作業數量增加時,堆積的請求數量劇增(如圖2所示),每一條請求的處理時間也較小規模時高出很多。
圖2 伏羲Master收消息隊列長度曲線
為什麼在伏羲Master隊列中會堆積如此多的消息?在伏羲系統中,守護進程伏羲Agent和AppMaster都需要向負責資源調度的伏羲Master查詢資源狀態,在通信策略上採用了定期Polling的方式,預設是每秒查詢一次。採用Polling通信方式主要基於其簡單性,能比較有效地應對網絡故障,消息傳遞發送過程比較自然有規律。然而在5000規模集群中,這個策略必須進行調整優化,否則會造成伏羲Master被大量請求「DDoS攻擊」而無法服務。
定位到消息堆積的問題後,我們立即對消息通信策略進行了流控,算法簡單有效:發送端檢查如果上次詢問的請求結果已經返回,表明目前伏羲Master請求處理較為順暢,則間隔一個較短的時間後進行下一次詢問。反之,如果上次詢問的請求超時,說明伏羲Master較忙(例如有任務釋放大批資源待處理等),發送端則等待較長時間後再發送請求。通過這種自適應流控的通信策略調整,伏羲Master消息堆積問題得到了有效解決。
此外,我們還解決了伏羲Master消息的隊頭阻塞(HoL)問題。AppMaster需要與伏羲Master通信獲得資源調度結果,同時也與伏羲Agent通信進行Worker的啟停。由於伏羲Agent數量遠大於伏羲Master,在極端情況下,如果AppMaster採用同一個線程池來處理這些消息,那麼伏羲Master消息會被前面大量的伏羲Agent消息阻塞。我們將消息處理的全路徑包括從發送到處理完畢等各個時間段進行了Profling,結果印證了隊頭阻塞現象。當一個任務的Worker較多時,AppMaster需要與之通信的伏羲Agent也會增多,觀察到AppMaster拿到資源的時間明顯變長。針對隊頭阻塞問題,我們通信組件中加入了獨立線程功能達到QoS的效果,並應用在AppMaster處理伏羲Master消息的通信中。如圖3所示,伏羲Master的消息單獨使用一個線程池,其餘消息則共用另一個線程池。
圖3 伏羲Master通信Qos示意圖
通過上面的兩項性能優化,伏羲系統內部的通信壓力得到顯著降低,提高了通信效率。AppMaster與伏羲Master之間的資源請求通信得到改善,任務提交後能很快分配到資源開始運行,提高了多並發任務場景下任務的完成速度。例如,經過這個優化,用戶通過ODPS客戶端對海量數據進行Ad hoc的SQL查詢處理速度能得到顯著提升。
在5K項目中我們還重點關注系統中的關鍵函數性能,那裡也可能藏著「陷阱」。伏羲Master在調度資源時的一個關鍵操作是:比較一個節點的空閒資源能否滿足該節點上排隊等待的所有資源請求,從而決定該資源分配給哪個任務。這個函數的調用次數會與機器規模和請求數量成正比,因此其速度對伏羲Master的調度OPS有決定性影響。
伏羲在調度資源時支持多個維度,如內存、CPU、網絡、磁碟等,所有的資源和請求都用一個多維的鍵值對表示,例如{Mem:10,CPU:50,net:40,disk:60}。因此,判斷一個空閒資源能否滿足一個資源請求的問題可以簡單地抽象成多維向量的比較問題,例如R:[r1,r2,r3,r4] > Q:[q1,q2,q3,q4],其中1、2、3、4等數字表示各個維度,若且唯若R各個維度均大於Q時才判斷R>Q。比較次數決定了這個操作的時間複雜度。最好情況下只需比較1次即可得出結果,如判斷[1,10,10,10]大於[2,1,1,1]失敗;最差需要D次(D為維度數),如判斷[10,10,10,1]大於[1,1,1,10]需比較4次。在資源調度高頻發生時,必須對這裡的比較進行優化。
我們通過Profiling分析了系統運行時資源空閒與請求情況,在資源充足時通常值最大的維度最難滿足,因此在資源調度場景我們採用基於主鍵的優化算法:對每個資源請求的最大值所在維度定義為該向量的主鍵,當有空閒資源時首先比較主鍵維度是否滿足請求,如果在主鍵上滿足再比較其他維度。此外,對一個節點上排隊等待所有請求的主鍵值再求一個最小值,空閒資源如果小於該最小值則無需再比較其他請求。通過主鍵算法,我們大大減少了資源調度時向量比較次數,伏羲Master一次調度時間優化到幾個毫秒。注意到資源請求提交後不會改變,因此計算主鍵的系統開銷可以忽略不計。
伏羲Master關鍵調度性能的優化增強了系統的規模擴展能力,用戶利用飛天平臺能管理更大規模的集群,容納更多的計算任務,發揮出雲計算平臺的成本優勢。
伏羲Master支持故障恢復,在重啟後進行故障恢復時需要從Nuwa讀取所有任務的描述文件(Checkpoint)以繼續運行用戶任務。考慮到之前Nuwa服務在伺服器端對文件內容沒有做持久化,伏羲Master在讀取了Checkpoint後還會再寫一次Nuwa,這個回寫操作性能依賴於Nuwa模塊。在5000節點的集群上,名字解析壓力的顯著增加導致Nuwa在Server的回寫操作上也出現了性能下降問題,最終通過模塊依賴傳遞到了伏羲Master,從而影響了故障恢復的性能。經測試觀察,一次Checkpoint回寫就消耗70秒,這大大降低了伏羲系統的可用性。
我們對伏羲Master故障恢復進行了優化。首先,從伏羲Master的角度,在故障恢復時剛剛讀取的Checkpoint內容在Nuwa伺服器端是不會發生改變的,因此讀取Checkpoint後沒有必要回寫到伺服器端,只需要通知本地的Nuwa Agent讓其代理即可,Agent會負責伺服器宕機重啟時向伺服器推送本地緩存的文件內容。於是與Nuwa團隊的同學合作,在Nuwa API中新增加一個只寫本地的接口,這樣伏羲Master規避了在故障恢復時回寫Checkpoint的性能風險。優化後,在5000節點集群和並發5000任務的測試規模下,一次故障恢復中處理Checkpoint操作僅需18秒(主要時間在一次讀取)。可見在分布式系統中,對外部模塊的依賴哪怕只是一個RPC請求也可能是「性能陷阱」,在設計和實現時儘量避免出現在關鍵路徑上。
故障恢復是分布式系統保證可用性必須具備的功能,經過優化,伏羲Master的快速故障恢復增強了飛天計算平臺的可用性和穩定性,屏蔽了硬體故障,使用戶的使用過程不受影響。
高質量代碼沒有捷徑可走,也不能只靠制度流程,唯有認真二字:作者認真、Reviewer認真、測試認真。
以上和大家分享了5K項目的一些實踐經驗,伏羲系統在5K項目中還做了很多有意義的系統優化和技術探索,參與其中收穫頗豐。性能是功能的一部分,是系統生死線而非錦上花。5K項目只是阿里雲計算平臺技術發展的一個開始,未來會在更大規模和更豐富計算模型等方面進一步發展,為用戶構築可用可靠的雲計算引擎,進一步降低成本,挖掘數據價值。
作者陶陽宇,阿里雲高級專家,中國科技大學博士,主要興趣和研究方向在大型分布式系統架構設計和性能優化方面,目前負責阿里雲飛天分布式調度系統的研發,包括在離線數據處理、在線服務框架、實時計算系統等。新浪微博:@陶陽宇_YY
本文為《程式設計師》原創文章,未經允許不得轉載,如需轉載請聯繫market#csdn.net(#換成@)