麵向容器的資源調度技術對比
本文以資源分配理念,拍賣、預算、搶占出發,引出Borg、Omega、Mesos、Kubernetes架構、數據、API的特點比較。然後梳理資源共享各種不同共享形式的內容,接著對比任務類型,最後回到資源利用率和基於數據預測角度,看相關係統是如何運用和實現各自場景目標。最後給出阿裏巴巴電商在線服務資源調度器Zeus關鍵技術內容。
進入這個領域的門檻不在具體某個技術,而業務場景和技術選型的映射匹配,特別是周邊係統的完善程度,決定了如何選擇方案、如何製定落地計劃。本文不是為了全麵分析某個調度器,也不是全麵對比某個關鍵點在不同調度器之間特色,而是基於筆者的理解,闡述在一個新場景下,如何設計或者完善一個資源調度器,從已有調度器係統吸取架構或模塊經驗,最低成本實現貼合自身業務場景的資源調度器。例如吸取調度器二層架構模式、數據集中管理方式、統一RestFull API、資源分時共享策略、在離線任務類型抽象等。
在資源調度器中,資源分配理念:拍賣、預算或搶占,往往是混合運用。資源分配理念,折射出了資源調度器所在的生態係統或者說周邊配合係統的成熟度、運行習慣。例如,Google從最早的廣告拍賣機製起,拍賣的理念在Google內部就形成了一種經驗,那麼資源競拍被分配出來的結果,大家很容易達成一致。而國內企業,往往是預算驅動,更趨向預算、采購,誰預算誰使用。這種環境下,資源被誰使用基本可以預見,成本也是比較容易找到歸屬者。在拍賣機製下資源搶占,初始分配是不大會發生,隻有在運行時發生資源不夠用的時候出現,低優先級的任務被Kill。在預算機製下,資源分配初期、運行時過程中,都會發生搶占。拍賣的另外一種好處是便於資源流動起來,不僅是資源利用率提升,更是資源投入產出比的最大化。而預算往往是一次性的,重點業務資源優先保障,使得適應性、靈活性、激勵業務效率提升變得不如拍賣。
不同策略落地在架構、數據、API層麵有著非常多的共同之處。從中不難發現Borg是始祖,後來的Mesos、Omega、Kubernetes、Zeus等都延續著Borg的某些重要特征,而又隨技術發展,引入新的特征。針對每個係統的具體分析,可以參照各係統發表過的論文及官方文檔[1,2,3,4,5,6,7]。
1.1 架構層麵
調度器架構圖如圖1所示[2],是Google建造的一個主控製核心,管理公司所有的數據庫。兩級優先級:服務性的高優先級和批處理的低優先級。兩階段調度:找到可行的節點,然後為最終放置對這些節點評分。
圖1 Borg架構圖
Borglet向Master匯報狀態,從而master確認borglet是否存活,以及是否需要執行Borglet上的任務遷移等操作。任務、資源的狀態數據更新是周期性的,而不是變化通知機製。
Job使用BCL來描述,通過RPC命令tool提交到Borg master。Borg大量的調度任務屬於Jobs,但是集群70%左右的CPU是給service的。
Borg 一層框架,在框架上跑Schedule。框架是Borglet和BorgMaster之間進行狀態通信,確保資源存活性、任務運行時數據收集,同時PAXOS協議,確保多master數據一致性,支持並發和容災。而Schedule與BorgMaster進行數據讀寫,實現資源的分配和回收管理等。
Twitter研發的超級網絡係統,Mesos的出現比YARN早,引入兩級調度的理念。兩級調度通過一個名為資源邀約的新API發起,邀約是有時間限製的,激勵應用程序去實現快速地調度。Mesos[3]裏麵並沒有拍賣的影子,更注重公平性,允許短任務預留一些資源。時間期限就是資源的共享的生命周期。在Mesos中,資源邀約是悲觀的或獨占的。如果資源已經提供給一個應用程序,同樣的資源將不能提供給另一個應用程序,直到邀約超時。
Borg和Mesos並不隻是能讓他們的服務器群智能化處理他們的數據,他們還讓管理集群就像操作一台機器一樣處理所有的數據[7]。
重點在介紹基於狀態的資源管理組件,Omega[4]的資源管理器基本上,隻是一個記錄每個節點狀態的關係數據庫,使用不同類型的樂觀並發控製解決衝突。這樣的好處是大大增加了調度器的性能(完全並行)和更好的利用率。
Omega采取多版本控製的、樂觀鎖機製在遇到偶爾的資源衝突時候。所有資源狀態存儲在基於PAXOS協議實現的事物係統中,外部調度器訪問並執行資源調度。
作為Docker生態圈中重要一員,由Google開源,整個設計重點之一在於方便分布式複雜應用的部署和管理[5,6]。Kubernetes吸收了Borg使用過程中大量的實踐經驗,當然整個係統因為涵蓋的功能較多,延續Borg完備、複雜性,相對Mesos等稍微簡單些。Kubernetes麵向雲端,需要考慮的功能點非常多。例如網絡、負載均衡、資源管理、高可用、鏡像更新、存儲、安全、監控等。Kubernetes架構如圖2所示。
圖2 Kubernetes架構圖
總結:主動、定時匯報的框架,還是變更通知的框架比較適合呢?狀態基於PAXOS協議分布式事務一致性,還是集中數據庫存儲?基於實踐的成本、簡單性、階段目標出發,變更通知和數據庫可以精簡係統、快速搭建原型。如果要應對百萬級服務器,那麼PAXOS協議、定時匯報應該就是標配的技術方案了。通知模式,消息重發(發的頻率、次數)、消息處理(髒數據、臨界數據)、數據補償等需要仔細設計,避免時不時的消息數據錯誤導致資源使用不一致,引發後續解救。PAXOS協議腦裂是一個潛在的風險,但是,相對通知模式還是顯得優雅和透明些。
兩級調度:第一級選擇機器(也就是業務編排),第二級分配容器資源。或者第一級選資源,第二級業務編排組織。這個過程,局部最優可以加速資源調度性能,全局最優可以獲取最佳的資源位。具體場景具體選擇,並且都可以作為參數傳入調度器。
兩種或多種優先級:高優先級、低優先級,分別對應在線服務、監控服務、運維服務,離線短周期Jobs、批量Jobs等。業務優先級的定義和變更,需要業務層麵全局的評估和係統自動化更新,並及時反饋到調度器中。業務方都趨向把自己的業務定位高優先級。確定不可搶占業務。
並發支持的程度和粒度,麵向鏈路也就是隊列,還是麵向資源狀態。每次申請資源全局最優還是局部最優,一旦發生衝突,樂觀鎖還是悲觀鎖。實踐經驗,先解決業務需求,求得生存,然後優化性能。
在整個架構之外,模擬器也是非常重要的子係統。尤其是資源調度器這種基礎的服務係統,資源一旦分配錯誤或者不可用,造成的影響非常大。整個結構友好的支持模擬數據進行算法驗證必不可少。總是假設,容器技術、生態的其他產品都是可信賴、高可用、跨語言API服務的。
1.2 數據層麵
在Google已經運行了10多年,是一個效率極高的係統。典型的Borgmaster使用10至14個內核和50GB內存,數據主要集中在內存。1分鍾啟停1萬個task進程。99%的Web UI響應時間小於1s,95%的polling borglet時間小於10s。針對成千上萬節點,每分鍾調度的速率為10K任務。典型調度時間是25秒左右(這依賴於具體節點的本地化。下載二進製占這個時長的80%,Torrent和樹協議用於分發二進製文件)。單個cell內部98%機器都是混跑(prod/non-prod, long-running service/batch jobs),整個Borg係統中83%的機器是混跑。意味著Google資源共享不是簡單的固定配額共享,又或者整機交付的共享,而是實時動態的共享。
在混部CPI方麵,增加作業會導致其他作業進程CPI增加0.3%(CPI越大表示程序執行越慢),機器CPU使用率每增加10%會導致作業進程CPI增加2%。混跑集群平均CPI 1.58,專用集群1.53。另外Borglet的CPI:混跑1.43,專用1.20。結論:CPI差別不大,因此混跑並不會顯著的降低程序運行時間!資源利用率主要的度量指標是單元壓縮。也就是一個業務單元使用的資源最小化程度。一個典型的cell中,prod作業調度占70% CPU,55%Memory,實際使用占60% CPU,85% Memory。通過Borglet的周期性、實時計算,調整資源實例的配額,從而進行資源壓縮。
配置或者Jobs調度參數等都以JSON或者YAML格式實現。
Google的效率,從Google一個PE可以運維上萬台服務器,可見相當先進了。
成本計費方麵:將Job的提交、配置、具體每個task的資源使用情況都保存到一個數據庫中,並提交SQL查詢,供計費、debug、錯誤分析、容量規劃。
更關注資源公平性,簡化了Borg的複雜性,做得相當薄,隻有10K行代碼。
典型的集群利用率約為60%。秒級的調度時間是典型的。
Google開源的Golang語言實現的、支持Docker容器的新一代資源調度器。和Borg Omega一樣,都有一個共享的持久化狀態存儲模塊,用於實現資源狀態一致性。Borg的Job Conf裏有230個參數,用戶tune代價大、易出錯,Kubernetes做了參數的自動化適應。
總結:數據也就是資源狀態以及調度分布數據,持久化DB還是Paxos協議實現的分布式事務存儲,沒有最好,隻有更好。不過,提供API查詢,特別是頁麵可視化操作,都是必須的。有時候對資源分配的結果,也是需要可解釋的,這依賴數據可視化、中間過程透明化。
流程或者分配或者運行時或者異常故障等數據的沉澱,用於故障分析、完善周邊係統、動態修正實例配額、容量水位、容量準入。數據沉澱並分析是非常有價值的。
成本計算基於調度器曆史過程申請資源的使用規模和時間,還是基於業務預算的資源,還是最後落地的流程記錄數據,不論哪種方式,對資源的粒度和時間片的統一界定非常重要。
所有對數據的操作在資源調度器層,盡量限製在原子層麵,流程或者業務數據一致性交給上層或者業務發起端控製。這樣,資源調度器層基本無狀態、原子更新,分布式一致性就比較簡單、集中。業務需求,交給業務處理。如果業務層校驗或者其他要求,資源不滿足需求,要麼業務層自我修複,要麼業務層要向鏈路下遊層層回滾,最終確保資源調度器資源申請和使用最終一致性。否則,資源數據不一致引發資源超賣或者資源提前“用完”,而實際有資源的尷尬。
1.3 API 層麵
緩存的機器分數、每種任務類型計算一次的可行性,在做調度決策時,不要試圖全局最優。複雜的規範語言。整個master是一個API server,其他的調度、admission管理都是作為服務,以client訪問API server,對外提供豐富的生態工具,例如腳本、web管理頁麵、控製台命令等。通過Http 協議實現的序列API,執行容器到資源分配管理的幾乎全部操作。支持以標簽形式動態調整應用的屬性,從而影響Jobs調度策略。
Mesos API[3]包括SchedulerHttp、Executor Http、internal C++ API。Mesos已經開始引入更多Kubernetes的概念來支持Kubernetes API [3]。仔細的比較Mesos、Kubernetes兩者的生態、開源社區發展,兩者之間的競爭是明顯的。虛擬機友好化、容器類(例如Docker)友好化的API或者二次開發,成為業界選擇的焦點。Mesos目前對計算集群支持的比較友好,而Kubernetes對虛擬機,尤其是雲端支持的更友好。
Omega 基於Borg發展起來的Google新一代係統,Omega論文並沒有給出詳細API說明。Omega重點在對比過去的架構和新架構的優勢,API猜測基本延續了Borg的相關功能。當對比討論Omega的時候,Mesos已經開源,許多概念已經在Mesos中實現了。當討論Kubernetes的時候,自然想到Mesos的衝擊力,並隨著Docker容器技術的興起、雲計算的發展,人們開始忘記Omega,似乎隻有Mesos和Kubernetes,以及共同的祖先Borg。
Kubernetes[5]從新開始,為不同調度器組件提供一套幹淨的API。Kubernetes做了參數的自動化適應。采用專門的RESTFULL API 提供服務。Kubernetes是用Golang語言寫的,它輕量、模塊化、可移植還有擴展性。
總結:參數JSON格式化、請求跨語言支持RESTFULLAPI,或者自定義一種描述語言。從麵向機器到麵向應用,調度器承擔的責任由薄到厚。不過,多語言、跨平台支持能力,特別是參數和響應格式的統一是基本要求。
API完整定義了調度器的功能邊界、服務規範程度、迭代升級效率、以及和周邊生態係統的交互形式等。從已知的序列資源調度器來看,Http協議、JSON格式參數和響應,沒有理由不遵守。
所有API的交互,建議異常信息貫穿整個鏈路,並且添加各個鏈路的標識,這樣在一個生態型的資源調度體係內,進行故障排查或者調試業務過程,具有非常大的便利性。
資源共享的過程離不開兩個維度:資源粒度、時間片。資源的效率=Σ(在線資源粒度*時間片*利用率) -Σ(資源離線粒度*時間片)。資源效率包括兩部分,在線部分和離線部分,離線部分主要是機器故障到恢複的過程,優化這部分資源效率,提升服務器在線率。軟硬件故障通用措施有:故障預警、故障檢測、故障自動修複、故障自動化處理流程等。效率簡單的按照在線減去離線,隻是為了描述:減少離線的浪費,有利於總體資源效率的提升。實際計算出來的數值不一定和真實現狀相一致的含義。下麵章節提到的資源共享,主要是在線資源部分。
不論哪種資源共享形式都沒有好壞之分,隻有合適與不合適服務的業務場景,並且最終有無實現資源的充分利用。往往是多種方式存在於一個大的係統裏麵。可能針對這個場景是固定配額,另外一個場景是動態配額,對於A業務是集群獨占,對於B業務是混合部署。
語言的差異也會影響共享方式。例如Java語言,對內存資源就沒法做到不重啟而動態調配內存。C++語言可以根據進程曆史內存消耗,動態地釋放內存給鄰居進程。而CPU、NETIO、DISKIO等,可以動態的分配資源占比。例如Borg,CPU、NETIO、DISKIO看作可壓縮資源,而Memory size、Disk Size不可壓縮資源。如果不可壓縮資源(如Mem,disk空間)緊張,Borglet立即開始殺進程,從低優先級開始直到資源不緊張。如果可壓縮資源(CPU,IO帶寬)緊張,Borglet開始約束進程的資源使用,優先保障latency-sensitive的進程(如long-running service)。如果仍然緊張,Borgmaster開始遷移走一些task進程。可以看出,Borglet不是固定配額給service和jobs,而是動態統一控製共享。運行時CPU等資源調配在Borglet端可以直接執行的,而不是外界主動發起、觸發BorgletAPI執行相應操作。
2.1 固定配額:悲觀
固定配額,是指實例啟動前和運行期間,實例占用的資源規格保持不變。或者物理機或者集群在混部過程,對某一類型的任務分配固定的資源占比。例如,單實例2個CPU邏輯核、4G Memory 空間、20G Disk 空間,磁盤IOPS、網絡IOPS 最大100MB/s 等。例如物理資源層麵,整個資源70%給在線服務,30%給離線服務。在線部分分配多個實例或者離線部分啟動多少JOB,資源總和不超過各自的比例上限。通常固定配額主要使用場景是在線Service。在線Service類型任務往往是long time running, 服務響應時間優先。在線服務即使需要資源壓縮,往往也是實例數量層麵,也就是容量水位層麵進行控製,幾乎不會執行動態的實例規格調整。不過也有例外,如果通過一段時間的數據收集處理,發現實例規格縮小或者放大,資源利用率更高或者響應時間更好,那麼,會執行新的規格升級。
2.2 動態配額:樂觀
動態配額,是指實例運行期間,CPU或Memory或NETIO等根據實時運行需求,進行動態的調配,隻要所在物理機資源夠用。動態配額模型,一旦支持動態的增加,也就意味著支持動態的減少,也就是一旦資源不夠用的時候,高優先級任務繼續運行,低優先級任務逼迫釋放資源,甚至Kill進程或者服務,進行硬降級。或者停止服務的某些子功能,釋放部分資源,進行軟降級。不難發現,動態配額往往是混部場景,並且被Kill的也是離線的JOBs。這帶來另外一個問題,離線JOBs管理模塊,能夠及時知曉JOBs的全局狀態,並及時重新在新的位置啟動Job,確保任務的總體Job數量和計算能力。
前麵提到,可壓縮資源可以做到平滑伸縮,不可壓縮資源往往需要實例重啟。對於C、C++ 伸縮更方便,伸縮時間片可以更小,而對於Java,成本相對較高,需要重新啟動JVM,伸縮時間片更大。
更大粒度的動態化,例如對在線service所在的實例集群,進行批量下線,批量釋放整機資源交給離線或者其他服務係統。時間片到了,離線任務被遷走,在線服務實例啟動。這種方式隔離比較徹底,在線和離線之間幾乎沒有影響。特別是在線、離線底層基礎環境不統一的時候,可以做到升級解耦。而對於基礎環境統一的係統,也可以方便在線、離線各自對物理機層麵的參數調整、充分挖掘物理機資源效率。
在一個大的資源體係內,可能A集群是更大粒度的動態化,B集群是小粒度的動態化。依賴周邊工具係統非常成熟,才能做到快速在線、離線環境隔離、環境上下文切換。並且調度係統能夠瞬時感知並支持集群容量變化。很好的實施大粒度變化,更依賴周邊係統工具。
2.3 分時租約共享
時間片的選擇,不是孤立的,往往和一定的資源共享粒度緊密相關。分時租約,在Mesos裏麵就是邀約方式,時間片到了,資源就強製釋放。租約的優勢在於,時間片的長度已知。對於離線任務,吞吐量優先的場景,那麼可以充分利用Jobs的運行時間,合理調配,充分進行資源的並發調度,提升吞吐量,包括錯開時間片內的峰值消耗。類似於流水線作業,讓CPU、IO、DISK合理發揮作用。
2.4 分時隨機共享
分時隨機共享,可以看作分時租約的一般化場景。隨機對資源粒度、時間片、上下文切換的能力要求更高。從Borg論文看,分時隨機共享,更多的是離線任務共享在線服務所在資源,資源一旦不夠用的時候,離線任務將被Kill。而在線任務壓力較低時候,IO等資源可以向離線任務傾斜而不影響在線服務的前提下。C++這種語言實現的任務特別適合,對JVM這種,隻能在CPU層麵實現隨機調整。
不論時間片的大小、時機的選擇,都需要一個強大的容器技術來實現資源的快速隔離、敏感的資源監控係統,進行資源消耗的追蹤、預測、調配。更上一層任務管理係統,能夠感知任務的存活和進度,並進行任務層麵的調度。
2.5 資源預留
資源預留,可以減少任務被Kill掉、被遷移的次數。在資源緊張的情況下,可以快速從預留的資源池,快速的影響資源請求。從彈性效率看,對於批量的、針對在線服務的容量水位控製,加速一次批量的成功率,特別是大資源坑位的快速交付,資源預留也是非常好的措施。從容災的角度,不同機房考慮其他機房整體不用的時候,承擔其他機房遷移過來的流量,相應的資源預留也有必要的。
資源預留的客觀性需求,必然犧牲一部分資源的利用率。恰當的預留規模就顯得非常必要了。至於預留多少,沒有絕對的指標。不同於銀行存款準備金率,該數值直接影響資金的流動。資源預留更多的是效率、應急響應所需。
資源調度器服務的任務類型,主要分為Jobs、Services。Jobs的特點:短周期,也有長的運行1天甚至1個禮拜的,大部分運行周期是分鍾級別;批量提交、運行;吞吐量優先;CPU、IO密集型;優先級相對低些;失敗後可以重新分配;函數式的過程,也就是多次運行結果,隻要輸入不變,結果也一致的。Service的特點:長周期,也有運行1天甚至1個禮拜的;活動營銷型服務;大部分運行周期是季度或者年的,提交後就一直運行;服務響應時間敏感;CPU、IO密集型都有;優先級特別高。有些基礎類型或者管控係統,有時候也作為service任務看待,這些係統不允許被搶占。例如,基礎存儲係統、監控運維係統、權限風控係統等,這些沒有直接服務外麵客戶,但對業務穩定性、可用性至關重要。做到任務資源不搶占,也就是固定配額模式,帶來好處:業務之間彼此的影響相對比較小。不好地方:資源分配不合理或者突發需求更多資源的時候,資源浪費或者資源吃緊。在一個大的資源調度管理生態係統中(周邊依賴非常多的工具、平台,而不是僅僅一個調度器就搞定),搶占必然發生的,搶占的對象、範圍、頻率、時機,在不同的場景下,以不同策略應對。
3.1 分配時搶占
分配時搶占,例如在不同優先級別任務共同部署在一個集群的時候,當出現更高優先級任務實例需要資源時候,空閑資源又不足以應付,此時,低優先級任務實例將被Kill,釋放資源。或者直接疊加到低優先級任務所在資源位置上。分配時搶占往往是約定的規則下執行的。為了最小化應用之間的影響,搶占盡量不集中在一個點或者一個應用或者一個業務層麵,風險分散式折中。任務能被Kill,默認要求被kill應用是無狀態的,這樣資源夠用的時候,可以自動恢複。另外搶占之後,即使從資源配額角度看,實例資源的訴求都滿足,從業務穩定性、綜合負載均衡看,熱點盡量避開。在高負荷運作的集群,添加資源或者釋放資源都需要綜合評估。
3.2 運行時搶占
運行時搶占,多半犧牲離線JOBs,如果離線JOBs沒有,那麼偶爾會犧牲在線低優先級Service。運行時搶占,對容器技術要求比較高,需要快速資源釋放、重新分配。在計算密集型場景下,CPU動態調配確實帶來非常好的效果。如果整個宿主機資源已經吃緊,再怎麼調配CPU,也不能緩解壓力。在線Service內存、磁盤空間大小往往不是瓶頸,磁盤IO、網絡帶寬的使用,可以進行軟降級。
對於被係統中斷等使用的CPU核,盡量不要使用這些計算資源服務應用。畢竟和係統中斷搶資源,非常不明智的。
基於Linuxcgroup 實現的CPU共享:CPU子係統和CPU set兩種方式,針對運行時的搶占效果的好壞,需要通過真實場景觀察確定。因為業務特征對效果有一定影響。業務對時間的敏感性,磁盤IO、網絡IO的隊列技術,就需要慎重使用。
資源利用率在第2部分已經提到,與資源粒度、時間片、利用率、服務器在線率等都有關聯。這些抽象層麵背後,還有那些方麵需要仔細實施,以確保最終的效率、利用率的提升。下麵列舉部分信息如下。
4.1 負載預測
負載預測,預測的實時性、準確性,應用實例規格的優化、運行時動態資源的分配、全局熱點把握,都是至關重要的前置技術。
負載數據主要包括CPU利用率、Memory消耗、Disk消耗,磁盤IO、網絡IO,甚至DB IO等。從這些曆史數據中,多維度對應用、應用實例層麵分別給出麵向不同時間片大小的預測值,其實是非常具有挑戰的事情。數據規模、采集的並發實時性,噪聲和突發流量甚至限流等,都對模型的響應時間、模型的準確率提出了很高的要求。因為錯誤的預測可能導致意想不到的調度影響。
負載預測和業務QPS、RT關聯起來,甚至和能源消耗、成本關聯起來,除了趨勢評估,還可以幫助決策。由此對數據的協同分析,也需要專業的團隊進行跟進。[12,13,14,15,16,17]
4.2 遷移最少
在資源調度係統甚至任何係統中,都會存在例外,存在係統規則或者模型無法應對或者之前沒有預估到的案例。遷移最少,大型資源池調度過程中,也是需要考量並優化的點。遷移成本,包括遷移的次數、遷移的規模、遷移的影響。
物理機故障不可避免,按照萬分之三的概率計算,一萬台服務器,每天大約3台服務器觸發硬件故障,這些硬件故障上麵的實例要麼直接不工作,要麼從新創建。無狀態的,直接擴容,有狀態的涉及到數據搬遷。
集群碎片整理或者負載整理,都需要對實例進行上線、下線操作。遷移的過程,其實就是服務資源“暫停”服務的過程。遷移次數、規模不得不考慮。
有時候就是純粹的資源替換,因為網絡或者機型或者業務需要,做到遷移最少,在資源預算或者業務規劃時候必須考量。看起來不是資源調度器的責任,但是,初期需要資源調度器的建議,從而降低二次梳理成本。
對於依賴性的JOBs,在業務開始時候,就應該考慮依賴關係。典型的數據搬遷、服務調用,做到同一機架或者交換機都帶來性能提升。一種遷移最少的方案參考論文[10]。
4.3 等待最短
在微觀層麵,資源調度器資源調度,特別是大規模Jobs調度,排隊以及排隊開銷客觀存在。排隊的長度和公平性,有時候很矛盾的。降低排隊時間,一方麵提升業務體驗,另外一方麵資源分配效率更高,資源在線工作時間片更多,資源利用率也就更好。
各種應對等待的隊列算法,例如輪詢、帶權值、優先級,都有各自的優缺點。具體場景需要具體選擇[8,9]。
4.4 碎片最少
碎片最少是默認的,實際選擇執行的路徑有所不同。空閑優先,也就是鋪開優先。另外一種是飽和優先,也就是緊湊優先。在相同資源、相同碎片的時候,是優先向空閑結點部署,還是將已有結點打飽和,沒有絕對的標準。方便大規格資源的申請,那麼打飽和比較妥當,這樣相同碎片量的情況下,大塊資源比較多。
在計算碎片的時候,需要綜合評估CPU、Memory、Disk等維度,通常CPU是核心競爭資源,優先評估CPU的碎片。確保CPU關鍵資源的充分利用,CPU資源在容器或者實例層麵,很容易動態調整而不需要重新實例化等。一些碎片最少的算法參考論文[11]。
如果實際分配過程中,確實存在碎片無法分配出一個資源位,那麼可以將餘下的CPU核綁定到已知實例上。雖然CPU資源利用起來了,如果上層流量均衡調度,那麼,這種相對其他實例多出的CPU資源,可以提升響應時間,但是並沒有提升QPS,隻對穩定性有幫助。
4.5 資損最少
VM代價計算模型當中,除了資源粒度、時間片等因素外,還需要考慮資損,尤其是電商交易類在線服務。服務器狀態異常或者故障,有時候會有造成用戶或者商家或者企業的財務損失。盡管業務架構層麵會極大程度規避這種情況的出現,實際過程中,如果把資損最少融入常規調度策略中,那麼,一旦發生局部集群的大麵積故障,資損理論上就降到最低。在已知的資源調度器中,代價更多的集中在資源本身,也就是IAAS層考量,而把業務層的需求,例如,資損最少交給PAAS或者SAAS層解決。從最初的小型機、商用數據庫、專有集群等,到分布式普通機器,自研發係統,不同階段的技術形態和投入是不一樣的。整個鏈路層麵,層層把控資損,其實最後落到資源調度器層麵的影響相對較少。
另外一個角度就是業務性價比,總是期望將業務收益最大、故障影響最敏感的係統,獨立部署,資源優先保障。例如廣告係統。
4.6 快速恢複
在有限資源的係統裏麵,或者高負載運作係統裏麵,局部故障的影響會被放大。在大規模的資源係統裏麵,每個應用的實例規模比較大,重啟或者上下線實例,幾乎沒有絲毫影響。失敗的流量占比幾乎可以忽略,失敗的請求重新分配到其他結點,對其他結點的壓力增長也是微小的。但是,幾乎每個結點壓力都達到閾值90%左右的話,那麼,即使是很少量的結點故障,影響也會放大。例如,秒殺或者搶購商品,實例的穩定性要求非常高。很難做到機器100%無故障,除了業務容量冗餘之外,故障快速恢複可以減輕故障影響。
和資損類似,故障快速恢複落到資源調度器層麵的責任或者壓力,其實非常微弱,甚至可以忽略,除非是特殊的業務。針對故障物理機承載的實例重啟速度的分布,進行有效的控製,可以從微觀層麵,提升故障的快速恢複能力。
在第一部分的架構、數據、API分析總結裏麵,已經把阿裏的一些實踐經驗概要描述了一下。本部分從整體上對Zeus進行概要總結。
5.1 上下遊架構
阿裏電商業務的複雜程度,很難用一個圖或一句話描述清楚。從資源調度的層麵看,阿裏的在線服務資源調度係統Zeus依賴或者配合的係統,多達十幾個。每一個被依賴的係統,除了服務資源調度器之外,還服務其他場景。下麵以Zeus實際運作過程中關聯或者依賴的視角,給出整體抽象架構示意圖,如圖3所示。
Zeus向下,依托阿裏自有IAAS服務,例如核心的容器技術,運維監控的底層通道係統。對上,銜接運維發布係統、監控視圖、環境巡檢、打標係統等等。Zeus提供資源調度過程和結果的可視化數據視圖。對接成本容量管控,在資源申請、回收、成本核算等整個資源生命周期,提供相關數據服務。
通過模擬演練,配合流量壓測、追蹤調度係統,提前發現不合理部署並自動調配。做到大促高峰流量場景下,業務的高可用,低成本開銷。
5.2 調度策略
基於預算的統籌安排,這意味著資源存在某種程度的“邊界”:就是“預算”。超出預算就變得很被動。為了提升資源利用率,負載均衡,需要跨資源邊界的共享,以共贏合作方式來推動。而Google Borg的競拍模式,從一開始資源是麵向所有組織業務、相對公平的。兩種模式選擇都不是憑空的,都是伴隨企業自身技術發展、貼合各自實際業務特征產生的。沒有優劣,隻有合適與否。
Zesu支持在線、離線混合部署。一種,在離線任務固定配額,在單機或者集群層麵固定配額,此時,在離線之間的資源爭搶是可以預知的,或者說資源的邊界不打破,理論上就不存在資源的幹擾。這種模式,有實踐過。另外一種,在線離線任務的運行時資源搶占,當在線任務資源緊張,單節點離線任務就需要釋放CPU或者磁盤IO或者網絡帶寬資源。
搶占發生的時刻,除了初始分配、也包括運行時時刻。例如,在線和離線之間搶占,甚至包括在線任務之間的資源搶占。
另外一種搶占,或者說資源傾斜,或者說業務管理需求吧。在線任務又細分中間件基礎服務、運維監控基礎服務、安全風險控製等業務模塊,這些重要的業務資源優先保障,不被搶占。
對待碎片,總體上碎片最少。候選資源結點排序上,鋪開優先和緊湊優先都有。看具體資源池和對應業務的需求而定。用於特殊場景下,甚至存在運行時動態確定資源的策略,例如秒級別響應資源服務需求。
故障預警、故障檢測、環境巡檢、打標、提升資源在線率、流程數據一致性等,也有相應的策略。例如:基於Golang實現的隊列,支持配置的批量更新、采集等。基於Golang 協程和Map,實現多級並發的機器選擇和計算得分排序等。
5.3 利用率和預測
資源利用率相對阿裏過去有不少提升,每年節約成本億為單位。相對業界,特定的資源池利用率達到甚至超過業界水平,總體打平的利用率,與業界還有一些差距。這些差距和業務場景、內部依賴配合的係統工具的成熟度、發展計劃都有關聯。
預測目標是某種程度把整個係統的流轉過程,數據化、模型化、自動化。預測的能力某種程度決定了資源調度係統最終能達到的理想狀態。在阿裏內部,針對在線或者離線任務的負載預測、容量水位預測、全鏈路模型等,都有相關的團隊在負責,並經曆了幾屆雙11的考驗,越來越穩定、高效、準確。具體預測模型、算法上麵,延續著業界已公開的論文,並結合阿裏業務場景,做適合業務發展需要裁剪實踐。
5.4 雲端調度
隨著雲計算的發展,電商混合雲部署架構的成熟。幾乎所有企業未來都麵臨雲端調度的問題。在雲端的資源調度、混合雲調度,對係統的協同能力、快速上下線能力提出了更高的要求。2015年雙11,充分利用了阿裏雲的公共雲計算資源來分擔一部分流量,阿裏、淘寶、支付寶在今年雙11做到了這一點,並且扛住了嚴酷的流量考驗。實現了交易上雲的關鍵技術的突破。未來,在雲端的交易更加普遍,雲端資源調度的技術、經驗更加豐富。在技術、經驗完善後,電商會分享給業界,讓大家享受雲帶來的低成本、便捷、高效。
最後更新:2017-06-28 17:02:23