曾 理 呂曉丹
1(貴州大學計算機科學與技術學院 貴州 貴陽 550025) 2(貴州省公共大數(shù)據重點實驗室 貴州 貴陽 550025)
微服務是一種將系統(tǒng)分解為小型、獨立、自治的服務體系結構,可以更輕松地在云環(huán)境中進行部署。它解決了傳統(tǒng)的單片架構隨著應用程序通過子模塊部署的應用擴展而降低了開發(fā)效率并增加了維護成本的問題。容器作為一種輕量級的虛擬化技術,在微服務的開發(fā)中起著重要的作用,可以大大提高部署環(huán)境的一致性并更好地利用資源。通常一種服務放置于一個容器中,因此微服務資源的彈性伸縮可以看成容器副本數(shù)的增加和減少。當前大多數(shù)資源調度都是針對傳統(tǒng)的虛擬機技術,但是傳統(tǒng)的虛擬機技術與容器技術本質上不同。容器的啟動速度以秒為單位,而虛擬環(huán)境的啟動一般需要5~15 min[1]。與裸機相比,容器的性能幾乎沒有損失,但是虛擬機有明顯損失?;谏鲜鋈萜鞯膬蓚€特征,可以更容易地實現(xiàn)容器數(shù)量的伸縮。
然而容器進行伸縮的時機尤為重要,伸縮算法的性能很大程度上取決于資源響應時間。云資源的自動伸縮的過程主要可以分為兩類:響應式和主動式[2]。響應式算法根據系統(tǒng)的當前狀態(tài)擴展,雖然這樣滿足實時和容易擴展的要求,但在準確性方面,由于云服務負載狀態(tài)變化頻繁和數(shù)據傳輸延遲等原因[3]使得獲得的負載值存在很大的滯后性,這樣可能會導致服務QoS下降,無法滿足客戶的要求,甚至會使得云服務提供商的成本增加[4]。主動式擴展方法適用于云環(huán)境,尤其是在負載突然增加或者減少的時候,預測算法可預測將來的需求,然后根據預測結果主動進行資源的自動伸縮。
多年來,工業(yè)界和學術界一直在積極地研究微服務中容器調度問題。在學術界有關微服務下的容器調度算法較少,因此尚未在該領域進行比較全面的比較評估。郭楊虎[5]提出基于鄰域劃分的容器調度策略,將依賴關系緊密的服務盡量放在同一臺物理服務器上,以減少系統(tǒng)調用。這種方法沒有考慮多副本的服務情況。文獻[6-8]根據當前資源使用情況通過提出動態(tài)容器調度策略,從而提高資源利用率。針對突發(fā)的服務負載,這種方法可能會降低QoS。文獻[9-11]通過時間序列預測方法對負載進行預測,根據預測結果對容器數(shù)量進行自動伸縮。但是并沒有對容器伸縮的數(shù)量進行量化。關于時間序列預測模型,目前 ARIMA模型在時序預測方面有比較廣泛的應用,文獻[10,12-13]選ARIMA來進行負載預測,雖然建模方式上有所不同,但通過使用基于預測模型的資源調度算法能夠及時、有效地保證云服務質量。
在工業(yè)界,為了解決容器的調度和復雜的管理問題,各大公司開發(fā)了自己的容器編排系統(tǒng)。其中比較著名的是Google公司的kubernetes、Docker公司的Swarmkit和Apache公司的Mesos[14]。然而Mesos主要的功能是數(shù)據中心資源的統(tǒng)一管理,其調度策略較少并且調度策略的實現(xiàn)和使用都比較復雜,對于非專業(yè)人員來說不太友好;Swarmkit[15]雖然原生支持docker,但它不能托管服務,開發(fā)人員要時刻運行服務發(fā)現(xiàn)引擎,并且對于版本的更新不能做到自動化;相較而言kubernetes提供了更加完善的功能,支持自動化的容器部署、擴展和管理。k8s以其強大的服務編排能力和服務管理能力在一眾編排系統(tǒng)中脫穎而出。但k8s在進行服務的擴縮容時,使用的擴縮容算法過于簡單,使得在服務面對突發(fā)負載時,無法保證服務的QoS。
綜合上述問題,本文通過使用時間序列預測模型根據最近一個時間區(qū)間內的容器負載數(shù)據,預測下一個時間區(qū)間內的負載。使用預先訓練的XGBoost模型,根據預測的負載壓力預測下一時間窗口內所需的服務容器數(shù)量。本文的主要貢獻如下:
1) 本文通過使用時間序列預測模型ARIMA根據最近一個時間區(qū)間內的pod負載數(shù)據,預測下一個時間區(qū)間內的負載,在負載突然上升或者下降時提供擴縮容時機。
2) 基于XGBoost模型,根據預測的負載壓力結合pod中CPU和內存使用率預測下一時間窗口內所需的微服務/容器數(shù)量。
ARMA是由Roy等[16]提出的一種對負載進行預測的時間序列模型。Calheiros等[17]在ARMA模型的基礎針對非平穩(wěn)的序列做了改進,提出差分自回歸移動模型ARIMA。ARIMA模型定義如下:
(1)
式中:p為自回歸階數(shù);φi是自相關系數(shù);L是滯后算子;d是差分項;Xt是原序列;q是差分階數(shù),θi是誤差項參數(shù);εt是誤差項。差分算子的計算為:
Wt=ΔdXt=(1-L)dXt
(2)
建立ARIMA模型整體流程如圖1所示。
圖1 ARIMA模型方法流程
ARIMA模型方法主要分為四個步驟:
1) 平穩(wěn)性檢驗。對于收集到的樣本數(shù)據,其中不乏非平穩(wěn)的序列,若存在上升或下降趨勢,則進行差分處理,消去其局部水平或者趨勢,得到的數(shù)據樣本就是平穩(wěn)的。
2) 模型識別。計算經過平穩(wěn)化后的數(shù)據序列的自相關函數(shù)(ACF)和偏自相關函數(shù)(PACF),然后分析相關函數(shù)圖進行模型識別如表1所示。
表1 ACF-PACF模型識別
自相關函數(shù)定義如下:
3) 模型定階。雖然觀察自相關和偏相關函數(shù)的拖尾和截尾可以給模型定階,但這種定階方法往往具有很強的主觀性。可以根據信息準則函數(shù)赤池信息準則AIC和貝葉斯信息準則BIC來確定模型階數(shù)。
AIC=2k-2ln(L)
(4)
BIC=kln(n)-2ln(L)
(5)
4) 模型檢驗。通過白噪聲進行檢驗,如果模型的噪聲訓練通過檢驗,那么模型完全或者基本符合了數(shù)據的相關性,如果不能通過噪聲檢驗,應該重新擬合模型直到通過白噪聲檢驗。
隨著云計算技術的興起,容器和微服務兩大技術應運而生,容器技術的發(fā)展為微服務提供了良好的客觀條件,而輕量級的容器技術則為微服務提供了最佳的運行環(huán)境。與此同時微服務架構所暴露出來的服務管理和服務發(fā)現(xiàn)等問題,促使了服務管理平臺的誕生。其中最優(yōu)秀的管理平臺是谷歌推出的kubernetes。圖2是基于k8s平臺的微服務部署架構。
圖2 基于k8s平臺的微服務部署架構
微服務與單體應用的區(qū)別在于一組微服務只使用一個代碼庫,實現(xiàn)單一的功能,每個服務可以獨立部署獨立發(fā)布,每個微服務放置于一個容器中。開發(fā)人員在部署微服務的時候,通常將一組服務放到一個pod中,同一個pod中的服務共享網絡與存儲,這樣可以使得服務間的通信能力大大提高。在微服務架構下,當負載急劇增加時,可以通過增加該pod中服務/容器數(shù)量,降低訪問壓力;相反pod中容器資源利用低下時,通過減少容器數(shù)量來達到節(jié)約資源的作用。因此負載發(fā)生變化時,服務/容器數(shù)量的伸縮數(shù)量至關重要。
為了解決上述問題,收集了大量有關負責壓力和所需容器數(shù)量的數(shù)據,建立了實驗數(shù)據集。每個樣本數(shù)據都包含了4個標簽,分別是CPU使用率、內存使用率、服務的負載壓力和容器數(shù)量。通過使用XGBoost算法,獲得服務的負載、CPU、內存使用情況和容器數(shù)量之間的關系,從而達到預測容器數(shù)量的目的。實驗有兩個約束條件,分別是服務質量QoS和資源利用情況。
XGBoost算法是在GBDT基礎上對Boosting算法進行改進的機器學習算法。為了防止模型出現(xiàn)過擬合,增強模型的泛化能力,加入模型復雜度的正則表達式項。同時對損失殘差使用二階泰勒展開。相較于其他分類算法,該算法的訓練速度和分類效果有著顯著的提升。
XGBoost是通過隨機地進行特征分裂來生成樹,也就是為了擬合前面預測的損失殘差,每次學習一個新的函數(shù)f(x),最后將k棵樹的結果求和作為最終的預測值。
(6)
Γ={f(x)=ωq(x)}(q:ω∈RT)
(7)
式中:xi代表第i個樣本;k表示樹的數(shù)量;T是對應樹的葉子節(jié)點個數(shù);q表示將樹與對應的葉子節(jié)點映射的空間結構;f(x)包括該樹的空間結構和葉子節(jié)點的權重;ω表示葉子節(jié)點的權重。
(8)
由于式(9)無法使用傳統(tǒng)方法進行優(yōu)化,因此在模型訓練時,使每一輪訓練都會保留前t-1模型的預測,這樣就大大減少計算復雜度,式(10)為新的目標函數(shù)。
(10)
為了方便計算損失函數(shù)L(φ),直接基于損失函數(shù)的二階泰勒展開式來求解,分別對損失進行一階導和二階導獲得:
通過把所有葉子節(jié)點區(qū)域和每個葉子節(jié)點區(qū)域最優(yōu)值訓練,將葉子節(jié)點最優(yōu)值代入目標函數(shù),最終的目標函數(shù)可以表示為:
(12)
最后目標函數(shù)基于最大分數(shù)對應的特征分裂子樹,通過不斷的迭代得到弱學習器,然后更新強學習器。
大量實驗表明CPU、內存、服務負載是調整容器數(shù)量的重要的三個因素。這三個特征組成特征樣本輸入XGBoost進行模型預測。算法步驟如算法1所示。
算法1基于XGBoost的容器數(shù)量預測算法
輸入: 訓練集S=(xi,yi),(xi+1,yi+1),…,(xn,yn),特征集合F。
輸出: XGBoost Tree。
function (S,F)
fork=1 to m do
GL=0,HL=0
foriin sorted(Ik,xik) do
GL=GL+gi,HL=HL+hi
GR=G-GL,HR=H-HL
end
end
Return The learned Tree XGBoost
end function
本實驗選取貴州翔明云科技公司微服務化的ERP系統(tǒng),部署于kubernetes平臺上。本實驗硬件環(huán)境:采用5臺戴爾服務器,內存:DDR3 1 066 MHz,CPU:E5506。其中:3臺服務器作為master節(jié)點,其中2臺既作為master節(jié)點也作為node節(jié)點;剩余2臺作為node節(jié)點。集群硬件環(huán)境如表2所示。
表2 集群硬件環(huán)境表
為了驗證時序預測方法的有效性,采集貴州翔明云的ERP系統(tǒng)五月到七月三個月的負載數(shù)據,從數(shù)據庫獲得負載數(shù)據,將前面三個月數(shù)據作為訓練集,選取后面8月1日8點到12點的數(shù)據作為測試集,然后使用ARIMA模型進行訓練,預測結果如圖3所示。
圖3 負載預測結果對比
可以看出本文的預測方法對突發(fā)負載保持了較好的預測精度,通過原始數(shù)據與預測數(shù)據曲線對比,ARIMA模型的預測方法能夠很好地預測負載。
為了驗證本文提出的XGBoost預測方法的有效性,對比kubernetes自帶的HPA(Horizontal Pod Autoscaler)算法。HPA通過Metrics API 獲取CPU、內存等資源信息,其算法原理是調整容器副本數(shù)目使得資源使用率盡量向期望值靠近,每次Pod伸縮的數(shù)量算法為:Ceil(當前采集到的資源使用率/用戶自定義的使用率)×Pod數(shù)量。
對比圖4和圖5可以發(fā)現(xiàn),在負載上升時,HPA算法并不能馬上做出擴容的反應;而本文方法能在負載上升之前擴容。在負載下降時,為了保證服務的QoS,將縮容的時機調整到負載下降之后。這里在擴縮容時是在不同物理服務器上進行,因此物理機負載變化影響較小。兩種方法縮容時機相同,但是縮容的數(shù)量不同。因此基于ARIMA-XGBoost的方法比HPA的方法在負載變化的云環(huán)境更適合,每次都在負載上升之前做好了擴容的準備。
圖4 HPA擴縮容過程
圖5 ARIMA-XGBoost擴縮容過程
為了驗證基于本文的方法比HPA算法好, 采用服務擴縮容響應時間和資源利用率情況兩個衡量指標?;?.3節(jié)容器擴縮容的過程,記錄下的服務響應時間對比如圖6和圖7所示,資源利用情況對比如圖8所示。
圖6 HPA方法擴縮容響應時間
圖7 ARIMA-XGBoost方法擴縮容響應時間
圖8 資源使用率對比
由圖6和圖7可以看到HPA算法在1~3 min時隨著負載的增加,沒能及時擴增容器數(shù)量,導致服務響應時間超出了200 ms(在云計算中服務的響應時間超過200 ms定義為服務質量低),而本文方法可以使服務的響應時間保持在200 ms以內。在15 min以后負載下降,兩種方法都沒有立刻縮容,因此服務響應時間均保持在200 ms以內。
由圖8可以看出在0~25 min的擴縮容的過程中,在保證服務質量的情況下,本文方法比HPA算法擴縮容的數(shù)量少,因此資源的使用率比HPA方法低,因此資源的利用率比HPA算法高。
本文通過使用ARIMA時序預測方法得知服務負載將來的變化,然后根據預測的負載結合pod中CPU、內存的使用情況使用XGBoost算法預測需要擴縮的微服務/容器數(shù)量,對比kubernetes的HPA算法,本文方法能在保證服務質量QoS的同時降低系統(tǒng)資源的使用。