阿里云分布式调度系统-伏羲
最近在做一個類似的東西,看了一篇講FuxiSort的paper,就去詳細學習了下。
paper鏈接:
鏈接: https://pan.baidu.com/s/1H9GdDd7lgcgWkw0tkC95Jw 提取碼: gix8
下文作者:陶陽宇,花名舉水,阿里云高級技術專家,飛天分布式系統早期核心開發人員,開發和優化過伏羲系統中多個功能模塊,參加了飛天5K、世界排序大賽等多個技術攻堅項目。在分布式計算、高并發系統的設計和開發方面有較豐富的經驗。
本文涉及阿里云分布式調度團隊在分布式調度系統的設計、實現、優化等方面的實踐以及由此總結的分布式系統設計的一般性原則,具體包括分布式調度的任務調度、資源調度、容錯機制、規模挑戰、安全與性能隔離以及未來發展方向六部分。
云計算并不是無中生有的概念,它將普通的單臺PC計算能力通過分布式調度軟件連接起來。其最核心的問題是如何把一百臺、一千臺、一萬臺機器高效地組織起來,靈活進行任務調度和管理,從而可以像使用臺式機一樣使用云計算。在云計算中,最核心的模塊是分布式調度,它好比云計算的中央處理器。目前,業界已存在多種分布式調度實現方案,如伏羲、Hadoop MapReduce、YARN、Mesos等系統。
阿里云伏羲
伏羲系統在前人的基礎上進行了一系列改造,首先與YARN和Mesos系統類似,將資源的調度和任務調度分離,形成兩層架構,使其具備以下優勢:
規模:兩層架構易于橫向擴展,資源管理和調度模塊僅負責資源的整體分配,不負責具體任務調度,可以輕松擴展集群節點規模;
容錯:當某個任務運行失敗不會影響其他任務的執行;同時資源調度失敗也不影響任務調度;
擴展性:不同的計算任務可以采用不同的參數配置和調度策略,同時支持資源搶占;
調度效率:計算framework決定資源的生命周期,可以復用資源,提高資源交互效率。
這套系統目前已經在阿里集團進行了大范圍的應用,能支持單集群5000節點、并發運行10000作業、30分鐘完成100T數據terasort,性能是Yahoo在Sort Benchmark的世界紀錄的兩倍。
伏羲的系統架構
伏羲的系統架構如圖1所示,整個集群包括一臺Fuxi Master以及多臺Tubo。其中Fuxi Master是集群的中控角色,負責資源的管理和調度;Tubo是每臺機器上都有的一個Agent,負責管理本臺機器上的用戶進程;同時集群中還有一個叫Package Manager的角色,因為用戶的可執行程序以及一些配置需要事先打成一個壓縮包并上傳到Package Manager上,Package Manager專門負責集群中包的分發。
集群部署完后,用戶通過Client端的工具向Fuxi Master提交計算任務;Fuxi Master接收到任務后首先通知某一個Tubo啟動這個計算任務所對應的APP Master;APP Master啟動之后,它獲知了自己的計算任務,包括數據分布在哪里、有多少的任務需要計算等等信息;接著APP Master會向Fuxi Master提交資源申請,表明它需要多少計算資源;Fuxi Master經過資源調度以后,將資源的分配結果下發給APP Master;APP Master在這個資源的基礎之上進行它的任務調度,來決定哪些機器上運行哪些計算任務,并且將這個計算任務發送給對應機器上的Tubo進程;Tubo接受到命令之后就會從Package Manager中下載對應的可執行程序并解壓;然后啟動用戶的可執行程序,加載用戶的配置(圖1中的APP Worker);APP Worker根據配置中的信息讀取文件存儲系統中的數據,然后進行計算并且將計算結果發往下一個APP Worker。其中,數據的切片稱之為Instance或者叫計算實例。
Fuxi Master與Tubo這套結構解決了分布式調度中的資源調度,每個計算任務的APP Master以及一組APP Worker組合起來解決任務調度的問題。
任務調度
伏羲在進行任務調度時,主要涉及兩個角色:計算框架所需的APP Master以及若干個APP Worker。
APP Master首先向Fuxi Master申請/釋放資源;拿到Fuxi Master分配的資源以后會調度相應的APP Worker到集群中的節點上,并分配Instance(數據切片)到APP Worker;APP Master同時還要負責APP Worker之間的數據傳遞以及最終匯總生成Job Status;同時為了達到容錯效果,APP Master還要負責管理APP Worker的生命周期,例如當發生故障之后它要負責重啟APP Worker。
而APP Worker的職責相對比較簡單,首先它需要接收App Master發來的Instance,并執行用戶計算邏輯;其次它需要不斷地向APP Master報告它的執行進度等運行狀態;其最為主要的任務是負責讀取輸入數據,將計算結果寫到輸出文件;此處的Instance是指輸入數據的切片。伏羲任務調度系統的技術要點主要包括數據的Locality、數據的Shuffle以及Instance重試和Backup Instance三點。
數據Locality
數據Locality是指調度時要考慮數據的親近性,也就是說APP Worker在處理數據時,盡量從本地的磁盤讀取數據,輸出也盡量寫到本地磁盤,避免遠程的讀寫。要實現這一目標,在任務調度時,盡量讓Instance(數據分片)數據最多的節點上的AppWorker來處理該Instance。
數據Shuffle
數據Shuffle指的是APP Worker之間的數據傳遞。在實際運行中,APP Worker之間是有多種傳遞形態的,如一對一、一對N、M對N等模式。如果用戶去處理不同形態的傳輸模式,勢必會帶來較大的代價。伏羲分布式調度系統將數據傳遞的過程封裝成streamline lib,用戶無需關心數據傳遞的細節。首先Map進行運算,將結果直接交給streamline,streamline底層會根據不同的配置將數據傳給下游計算任務的streamline;然后streamline將接到的數據交給上層的計算任務。
Instance重試和backup instance
在Instance的運行過程中可能有多種原因導致Instance失敗,比如APP Worker進程重啟或運行時機器、磁盤發生故障,種種原因都可能導致一個Instance在運行時最終失敗;另外APP Master還會監控Instance的運行速度,如果發現Instance運行非常慢(容易造成長尾),會在另外的APP Worker上同時運行該Instance,也就是同時有兩個APP Worker處理同一份數據,APP Master會選取最先結束的結果為最終結果。判斷一個Instance運行緩慢的依據有:
該Instance運行時間超過其他Instance的平均運行時間;
該Instance數據處理速度低于其他Instance平均值;
目前已完成的Instance比例,防止在整體任務運行初期發生誤判。
資源調度
資源調度要考慮幾個目標:一是集群資源利用率最大化;二是每個任務的資源等待時間最小化;三是能分組控制資源配額;四是能支持臨時緊急任務。在飛天分布式系統中,Fuxi Master與Tubo兩者配合完成資源調度。
在飛天分布式系統中,Fuxi Master與Tubo兩者配合完成資源調度。Tubo是每個節點都有的,用于收集每個機器的硬件資源(CPU、Memory、Disk、Net),并發送給FuxiMaster;FuxiMaster是中控節點,負責整個集群的資源調度。當啟動計算任務時,會生成APP Master,它根據自己的需要向Fuxi Master申請資源,當計算完成不再需要時,歸還該資源。
飛天分布式調度常用的分配資源策略包括優先級和搶占、公平調度、配額。在實際應用場景中,不同策略可配合起來使用。
策略之優先級和搶占
每個Job在提交時會帶一個priority值(整數值),該值越小優先級越高;相同優先級按提交時間,先提交的優先級高;FuxiMaster在調度時,資源優先分配給高優先級的Job,剩余的資源繼續分配給次高優先級Job。
如果臨時有高優先級的緊急任務加入,FuxiMaster會從當前正在運行的任務中,從最低優先級任務開始強制收回資源,以分配給緊急任務,此過程稱為“搶占”。搶占遞歸進行,直到被搶任務優先級不高于緊急任務,也就是不能搶占比自己優先級高的任務。
策略之公平調度
公平調度策略是指當有資源時Fuxi Master依次輪詢地將部分資源分配給各個Job,它避免了較大Job搶占全部資源導致其他Job餓死現象發生。公平調度首先按優先級分組,同一優先級組內的平均分配,如果有剩余資源再去下一個優先級組進行分配,依此類推。
配額
配額是資源分配時的第三個策略,通常是按照不同的業務進行區分,多個任務組成一個組,例如淘寶、支付寶等;集群管理員會設立每一個組的資源上限,意味著這個組最多能使用這么多CPU、Memory、磁盤等,該上限值稱為Quota;每個組的Job所分配的資源總和不會超過該組內的Quota,當然如果每一個組內沒有用完的Quota是可以分享給其他組的,會按照Quota的比例進行均分。
容錯機制
在大規模進程集群中故障是常態,這些常態會來自硬件,比如主板、電源、內存條;也可能來自軟件,比如進程有Bug導致進程Crash,機器故障導致性能慢。因此,分布式調度必須具有容錯機制,以保證正在運行的任務不受影響,并對用戶透明,能夠從故障中恢復過來,保障系統的高可用。下面將從任務調度的Failover和資源調度的Failover兩個方面介紹。
AppMaster進程重啟后的任務調度Failover
每個計算任務有自己的APP Master,如果APP Master進程發生了重啟,那其重啟之后的任務調度如何進行Failover呢?這里采用了Snapshot機制,它將Instance的運行進度保存下來,當APP Master重啟之后會自動加載Snapshot以獲取之前每個Instance的執行進度,然后繼續運行Instance;當APP Master進程重啟之后,從APP Worker匯報的狀態中重建出之前的調度結果,繼續運行Instance。
FuxiMaster進程重啟后的資源調度Failover
另一種情況是Fuxi Master發生了Failover。Fuxi Master Failover起來之后需要重建內部狀態,該狀態通常分為兩種:一是Hard State,主要是之前提交的Application配置信息,如不同的Job配置參數等,它們來自于Fuxi Master寫的Snapshot;另一類是Soft State,Fuxi Master會收集來自各個Tubo以及APP Master的信息重建出自己的狀態,這些信息包括機器列表、每個APP Master的資源請求以及之前的資源分配結果。
Fuxi Master進程重啟之后的資源調度過程如圖4所示,首先會從Checkpoint中讀取出所有Job的配置信息;同時會收集所有的Tubo以及APP Master上報上來的關于資源分配的結果,如CPU多少、Memory多少等等。
規模挑戰
分布式系統設計主要目標之一就是橫向擴展(scale-out),目前阿里云飛天在2013年時已支撐單個集群5000個節點、并發1萬個任務。在做橫向擴展設計時,需要注意兩個要點:一是多線程異步;二是增量的資源調度。
多線程異步
多線程異步是編寫分布式程序一個非常重要而且常用的技術手段。在網絡通信模塊中,每個APP Master都需要跟Fuxi Master進行資源通信,同時也需要跟多個Tubo進行通信以啟動它們的APP Worker。APP Master處理網絡通信的過程稱之為RPC,RPC通信時必須采用線程池來處理。如圖5中采用四個線程池來處理這些消息。由于Fuxi Master是一個中控節點,而Tubo的數量非常眾多,如果將這些消息都在同一個線程池中處理,則Fuxi Master的消息有可能會被大量的Tubo消息阻塞(對頭阻塞問題)。為了解決該問題,在伏羲系統當中設立了一個獨立的線程池來處理Fuxi Master的消息;另外一個線程池來處理Tubo的消息,將線程池進行分開,也稱之為泳道;獨立的泳道能有效解決Fuxi Master的消息被對頭阻塞的問題。
增量的資源調度
伏羲解決規模問題的另一個技術點是增量。目前,伏羲采用增量的消息通信和資源調度,下面通過具體例子,來介紹伏羲所采用的增量資源調度的協議。
圖6左側是中控節點Fuxi Master;右邊為某一個APP Master,如果說APP Master需要1000份資源,最直接的一種實現方式是將“我要1000個資源”這樣的消息直接發送給Fuxi Master;Fuxi Master在接到消息之后可能當前的剩余資源只有200份,它將會“我分配給你200”這樣的消息發送給APP Master;那APP Master還會繼續發送消息“我還要剩余的800”,Fuxi Master回復“此時沒有資源,我分配0個給你”;則APP Master在下一次通信的時候需要繼續發送“我還要剩余的800”……依此類推,可能某一個時刻Fuxi Master還能分一點資源下來。這就是最直觀的全量消息通信,每一次APP Master提出請求時都要指明它總共需要多少。
而在伏羲的實現當中為了減小通信量和不必要的開銷,采用了增量的語義。首先APP Master發送一個請求“我要1000個資源”,Fuxi Master收到之后將當時空閑的200個資源返回給APP Master;之后APP Master無需再提交請求說我還需要800,因為Fuxi Master會將這1000個請求記錄下來等到某一時刻又有更多的資源,比如150個資源釋放,它直接將150個分配結果發送給APP Master即可。這期間APP Master無需再發多余的網絡通信。
安全與性能隔離
在分布式系統當中通常有多個用戶在執行自己的計算任務,多個任務之間需要互相隔離、互相不影響。飛天伏羲實現了全鏈路的訪問控制,采用了兩種訪問控制進行安全的驗證,一種是Capability,指通信雙方基于私鑰進行解密并驗證的一種方式;還有一種稱為Token的方式,這種方式需要通信的雙方臨時生成基于私鑰加密的口令,在通信時進行驗證。
兩種方式最大區別在于口令生成的時機,Capability方式是在通信之前就已經加密好;而Token是需要在通信時臨時生成。
兩種方式使用于不同的場景,如圖7所示FuxiMaster與Tubo通信采用的是Capability方式,因為這兩個角色在集群部署時就已啟動,可以事先進行加密生成好Capability;FuxiMaster與APP之間是采用Token的方式,這是因為APP與FuxiMaster進行通信時,當每個任務執行完計算之后會退出;在進程與進程之間,伏羲采用了沙箱的方式將不同的進程進行隔離開、互不干擾。
除了安全的隔離之外,還需要考慮性能的隔離。目前伏羲采用的幾種技術手段:Cgroup(Linux LXC)、Docker container、VM等。這幾種技術的隔離性、資源配額/度量、移動性、安全性的比較如圖8所示,不再一一敘述。
伏羲目前采用的隔離技術是基于Docker和LXC混合部署的方式,之所以拋棄虛擬機的方式,是因為其性能損耗太多。當運行計算任務時,如果完全放在虛擬機當中,它的IO以及CPU時間片會受到很大的影響,會降低任務的執行效率。在目前阿里的生產環境中,實踐發現基于Docker和LXC的隔離技術已經可以很好地滿足需求。
分布式調度的發展方向
隨著計算能力和數據量的持續增長,分布式調度未來可能朝向以下幾個方向發展:
在線服務與離線任務混跑。云計算最終的目的是降低IT成本,最大限度地利用單臺PC的CPU處理能力,所以未來的趨勢一定是在線服務與離線任務能夠在同一物理集群上運行從而實現削峰填谷效果、最大化提高集群利用率。但是由于兩種任務的特點不同,在線運用對于響應時間要求很高,而離線運用則對調度的吞吐率要求比較高,因此混跑會帶來性能隔離與資源利用率之間的矛盾。
實時計算的發展,Map Reduce是一個很偉大的框架,但其是為數據量一定的批處理而設計的。隨著云計算越來越普及,很多計算形態需要實時拿到計算結果,并且其輸入數據可能是不間斷的。目前,伏羲也已經開發出了實時的計算框架——OnlineJob,它可以提供更快的執行速度。
更大的規模,目前已能夠支撐5000臺的節點,隨著計算量越來越大,客戶的需求越來越多,需要進一步優化伏羲系統,能夠支撐起1萬、5萬、10萬等更大規模單集群,同時能夠支撐更多的并發任務。
總結
以上是生活随笔為你收集整理的阿里云分布式调度系统-伏羲的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机九宫格游戏怎么玩,《九宫格数独》怎
- 下一篇: C++ - Sodoku Killer(