李東光,劉智平,姜雨菲
(西安工業(yè)大學(xué) 計(jì)算機(jī)科學(xué)與工程學(xué)院,西安 710021)
容器技術(shù)在近年的軟件部署方面為主要的新技術(shù),Docker[1]作為一種典型的容器技術(shù),其自帶的集群編排工具Swarm在調(diào)度資源時(shí)存在負(fù)載不均,集群整體性能差的問題,無(wú)法完美實(shí)現(xiàn)負(fù)載均衡,在資源利用率和集群性能方面并不能很好的符合預(yù)期。
國(guó)內(nèi)外對(duì)此問題有較多的研究,在資源調(diào)度方面,文獻(xiàn)[2]基于原有的 Swarm 容器集群管理工具,另外加入權(quán)值調(diào)度模塊。在接收到Client的請(qǐng)求時(shí),利用權(quán)值調(diào)度模塊根據(jù)各個(gè)節(jié)點(diǎn)的資源消耗情況計(jì)算出節(jié)點(diǎn)權(quán)值,按照約定,權(quán)值越高表名節(jié)點(diǎn)的總體資源占用率越大,鑒于此,權(quán)值調(diào)度模塊會(huì)把新的容器放在權(quán)值最小的節(jié)點(diǎn)來(lái)實(shí)現(xiàn)集群負(fù)載均衡。此策略在一定程度上實(shí)現(xiàn)了容器集群的負(fù)載均衡,但是此策略只考慮到了整個(gè)容器的資源分配,并未對(duì)不同的資源類型做更為詳細(xì)的權(quán)值計(jì)算,并不能保證所利用即為所分配。文獻(xiàn)[3]在容器虛擬化中引入了機(jī)器學(xué)習(xí)算法,利用K-Medoid算法、分割周圍類算法等實(shí)現(xiàn)了容器代理系統(tǒng),此系統(tǒng)具有容器工作負(fù)載感知的能力,節(jié)約能耗的同時(shí)也保證了集群的整體性能。文獻(xiàn)[4]基于自回歸積分滑動(dòng)平均模型提出了云計(jì)算負(fù)載預(yù)測(cè)模型,達(dá)到了91%的準(zhǔn)確率。然而,計(jì)算學(xué)習(xí)調(diào)度策略在容器集群調(diào)度中能否發(fā)揮其優(yōu)勢(shì)需要視情況而定,機(jī)器學(xué)習(xí)算法是依托于大量的樣本訓(xùn)練集,對(duì)于容器集群來(lái)說(shuō)即是大量的時(shí)間序列和容器資源使用量,如此龐大的開銷使得其優(yōu)勢(shì)并不是十分明顯。
因此,文中綜合各個(gè)調(diào)度算法的優(yōu)劣,擬采用一種啟發(fā)式智能算法蟻群算法[5-8](Ant Colony Optimization,ACO),其在解決這類組合優(yōu)化的問題具有一定的優(yōu)勢(shì),文中擬通過使用蟻群算法對(duì)部署Swarm集群調(diào)度進(jìn)行改進(jìn),實(shí)現(xiàn)Swarm集群各節(jié)點(diǎn)主機(jī)任務(wù)相對(duì)均衡分布,同時(shí)提高集群的整體性能。
傳統(tǒng)的虛擬機(jī)一般由兩部分構(gòu)成,虛擬硬件和操作系統(tǒng);而Docker創(chuàng)建的虛擬機(jī)即容器[9]并不需要?jiǎng)?chuàng)建安裝特定的操作系統(tǒng)和Hypervisor管理,而是直接共享主機(jī)操作系統(tǒng)的內(nèi)核,用Host主機(jī)的硬件和操作系統(tǒng)來(lái)執(zhí)行程序。由于容器沒有中間件消耗資源,一定程度上提高了資源的利用率,兩者的系統(tǒng)架構(gòu)對(duì)比如圖1所示。
圖1 傳統(tǒng)VM和Docker的比較
集群結(jié)構(gòu)如圖2所示,Swarm[10]使用標(biāo)準(zhǔn)的Docker API接口作為其前端訪問入口,并以守護(hù)程序的形式運(yùn)行,對(duì)來(lái)自Docker Client的指令信息進(jìn)行配置,并最終以代理的形式將需要處理的信息發(fā)送給不同節(jié)點(diǎn)的Docker Daemon進(jìn)行處理并返回響應(yīng)。
Swarm中提供了三種不同的資源調(diào)度策略[11]Random、Spread和Binpack。Random策略采用隨機(jī)分配容器的部署位置,這種調(diào)度方式有很大缺點(diǎn),一般僅限于集群的測(cè)試;Spread策略按照各節(jié)點(diǎn)資源即內(nèi)存和 CPU 內(nèi)核數(shù)來(lái)決定部署的容器數(shù)量,此方式能夠讓容器相對(duì)均勻地分布在主機(jī)各個(gè)節(jié)點(diǎn)上;而Binpack策略會(huì)先將一個(gè)節(jié)點(diǎn)的資源用盡之后再向其他的節(jié)點(diǎn)部署容器,此方式調(diào)度可以充分使用每個(gè)節(jié)點(diǎn)資源,但會(huì)導(dǎo)致各節(jié)點(diǎn)任務(wù)負(fù)載嚴(yán)重不均,影響集群的整體性能表現(xiàn)。Swarm內(nèi)置的這三種不同的調(diào)度方式,可以應(yīng)用在一些對(duì)集群效率要求不高的應(yīng)用中。但對(duì)于類似云平臺(tái)的應(yīng)用,對(duì)于集群的負(fù)載均衡,資源利用率要求較高,對(duì)集群的整體性能表現(xiàn)有一定的高要求,在這些情況下,Docker Swarm內(nèi)置的調(diào)度策略有明顯的缺陷[12]。
圖2 Docker Swarm集群系統(tǒng)架構(gòu)圖
Docker集群是由2組節(jié)點(diǎn)即管理節(jié)點(diǎn)和工作節(jié)點(diǎn)組成。而管理節(jié)點(diǎn)也負(fù)責(zé)任務(wù)管理,包括調(diào)度決策。SwarmKit為Docker集群管理背后的真正引擎。開始調(diào)度之前,所有的工作節(jié)點(diǎn)將通過一組過濾器進(jìn)行處理,例如Constraint Filter只允許滿足指定約束的節(jié)點(diǎn)通過。之后使用調(diào)度算法ACO替代原始循環(huán)貪婪算法將任務(wù)組放入流水線調(diào)度,總體的結(jié)構(gòu)如圖3所示。
在Docker的最新版本中,提供了服務(wù)和任務(wù)的概念。服務(wù)由一個(gè)或多個(gè)任務(wù)組成。集群用戶將通過向調(diào)度器提交一些任務(wù)來(lái)啟動(dòng)服務(wù)。調(diào)度器選擇一組符合指定約束的節(jié)點(diǎn),并將任務(wù)調(diào)度到這些節(jié)點(diǎn)。總是會(huì)同時(shí)安排一批任務(wù),但不一定是同時(shí)完成所有任務(wù)。在每批任務(wù)中,都可以使用他們所要獲取資源的信息來(lái)找到最佳方案,并使用ACO技術(shù)。
圖3 ACO算法下的SwarmKit調(diào)度結(jié)構(gòu)圖
調(diào)度器目標(biāo)是將任務(wù)放到可用資源上。他在每次調(diào)度時(shí)會(huì)使用可用資源。一個(gè)人工螞蟻通過觀察每一個(gè)資源的信息素軌跡來(lái)隨機(jī)尋找資源。某個(gè)節(jié)點(diǎn)的每個(gè)資源的計(jì)算公式為
(1)
為了初始化每個(gè)節(jié)點(diǎn)的信息素軌跡,在循環(huán)貪婪算法中使用R(j),其簡(jiǎn)單地將每個(gè)任務(wù)放在循環(huán)模式的一個(gè)節(jié)點(diǎn)上,τ0,j=R(j)為每個(gè)節(jié)點(diǎn)的起始信息素。
每個(gè)概率的計(jì)算公式為
(2)
其中ηi為節(jié)點(diǎn)j的啟發(fā)式值。
計(jì)算每個(gè)節(jié)點(diǎn)的概率p(t,j),選擇下一個(gè)節(jié)點(diǎn)j
(3)
其中j∈P(k),q0為探索率。
下一步計(jì)算信息素消失。每個(gè)節(jié)點(diǎn)的信息素軌跡消失計(jì)算公式為
(4)
其中Δ表示信息素的變化,當(dāng)一個(gè)任務(wù)被調(diào)度程序放置到一個(gè)特定的資源,Δ的值總是小于0。信息素利用式(4)計(jì)算,為了顯著地減少所選節(jié)點(diǎn)的信息素水平,使其對(duì)下一個(gè)任務(wù)不那么重要,使得剩余的容器將被分配到整個(gè)資源中。
最佳的規(guī)劃Pw采用式(5)從所有任務(wù)中選出最頻繁規(guī)劃。
(5)
在實(shí)現(xiàn)真正的調(diào)度程序之前,通過模擬輸入數(shù)據(jù)并執(zhí)行單元測(cè)試將其作為模擬運(yùn)行,發(fā)現(xiàn)最佳規(guī)劃的頻率范圍為0.35~0.70。
文中參數(shù)的選擇通過大量的實(shí)驗(yàn)對(duì)比得來(lái),經(jīng)過測(cè)試,使得算法在收斂度,穩(wěn)定性以及保障性能的基礎(chǔ)上,α,β,ρ分別選擇 0.7,0.3,0.6。
SwarmKit和Docker都是使用Go編程語(yǔ)言編寫的。文中使用Go 1.6.2作為編譯器,利用Docker支持的主要平臺(tái)x86-64架構(gòu)完成。通過在云提供商DigitalOcean上形成SwarmKit集群來(lái)進(jìn)行實(shí)驗(yàn)。該集群由1個(gè)管理節(jié)點(diǎn)和5個(gè)在同一數(shù)據(jù)中心上運(yùn)行的工作節(jié)點(diǎn)組成。表1為5個(gè)工作節(jié)點(diǎn)的資源配置情況。SwarmKit管理器將管理節(jié)點(diǎn)可用性設(shè)置為零,以防止將容器調(diào)度到自身。每個(gè)工作節(jié)點(diǎn)都連接到同一主機(jī)上的每個(gè)Docker引擎。實(shí)驗(yàn)一通過使用SwarmKit附帶的原始循環(huán)貪婪算法實(shí)現(xiàn)完成,實(shí)驗(yàn)二通過使用ACO算法調(diào)度器的SwarmKit容器的修改版本完成。實(shí)驗(yàn)結(jié)果分別以 Spread和ACO表示。
表1 Docker主機(jī)各節(jié)點(diǎn)的資源配置
選擇部署普通的NGINX服務(wù)器作為調(diào)度任務(wù),NGINX服務(wù)器的CPU和內(nèi)存預(yù)留量分別為0.5和128 MB。在5個(gè)節(jié)點(diǎn)上部署了12個(gè)NGINX服務(wù)器任務(wù),部署統(tǒng)一的任務(wù)可以很容易地觀察結(jié)果的調(diào)度。圖4和圖5分別顯示了由 Spread和ACO算法計(jì)算的調(diào)度計(jì)劃。將最大資源節(jié)點(diǎn)即節(jié)點(diǎn)二進(jìn)行資源歸一化即為1。同樣把每個(gè)NGINX服務(wù)器所占資源進(jìn)行歸一化處理??梢缘玫讲渴鹈總€(gè)NGINX服務(wù)器所占資源為0.125,從圖4和圖5中可以看出每個(gè)節(jié)點(diǎn)部署的NGINX服務(wù)器個(gè)數(shù),縱軸上的資源從式(1)中得出。
圖4 Spread策略各節(jié)點(diǎn)任務(wù)分配
圖4中,對(duì)于SwarmKit的Spread策略,將前10個(gè)任務(wù)平均分配給所有5個(gè)節(jié)點(diǎn),對(duì)于最后2個(gè)任務(wù),選擇分別將它們放到節(jié)點(diǎn)2和節(jié)點(diǎn)4, 這導(dǎo)致節(jié)點(diǎn)2和節(jié)點(diǎn)4在每個(gè)節(jié)點(diǎn)上運(yùn)行3個(gè)容器。
圖5 ACO算法各節(jié)點(diǎn)任務(wù)分配
圖5中,只有任務(wù)被放入每個(gè)512中MB節(jié)點(diǎn),節(jié)點(diǎn)1和節(jié)點(diǎn)5。具有4GB規(guī)格的節(jié)點(diǎn)2和具有2GB規(guī)格的節(jié)點(diǎn)4分別用于調(diào)度4個(gè)任務(wù)。實(shí)際上,放置在所選計(jì)劃中的序列Pw將任務(wù)放入節(jié)點(diǎn)2中,在節(jié)點(diǎn)4,節(jié)點(diǎn)2和節(jié)點(diǎn)3之間來(lái)回切換。節(jié)點(diǎn)3用于調(diào)度2個(gè)任務(wù)。
通過對(duì)比兩個(gè)算法的任務(wù)調(diào)度可以看出ACO相對(duì)Spread實(shí)現(xiàn)了更好的均衡負(fù)載。
任務(wù)分配的結(jié)果并不是主要問題。最終目標(biāo)是提升集群的整體性能。因此,在部署之后,文中使用Apache Bench來(lái)測(cè)量NGINX服務(wù)器的性能。測(cè)試配置為“-c10-n1000”。
表2為ACO和Spread策略放置的每個(gè) NGINX 容器壓力測(cè)試數(shù)據(jù)。此處容器對(duì)應(yīng)的兩種算法中的容器可能不是同一節(jié)點(diǎn)的容器,只是為了統(tǒng)計(jì)整體性能。上一節(jié)使用ACO算法放置容器可以使任務(wù)更均勻分布,雖然,不能顯示哪個(gè)容器在哪個(gè)主機(jī)節(jié)點(diǎn)上運(yùn)行,但是通過對(duì)集群容器集群進(jìn)行壓力測(cè)試可以得出優(yōu)劣,Spread中總負(fù)載為22 186.21,ACO中總負(fù)載為26 623.034,很明顯,ACO算法調(diào)度的集群的整體壓力測(cè)試性能要好于原始的調(diào)度性能。同樣的環(huán)境下,基于ACO集群QPS相對(duì)Spread集群提高約20%。
表2 Docker集群下Spreed策略和ACO算法部署容器數(shù)據(jù)對(duì)比
目前在Docker主機(jī)中以循環(huán)方式分發(fā)容器,循環(huán)算法導(dǎo)致資源使用并不理想。文中提出了一種基于ACO的算法用在軟件容器環(huán)境Docker中調(diào)度任務(wù),發(fā)現(xiàn)Swarm的當(dāng)前實(shí)現(xiàn)模型與ACO非常吻合,通過搭建容器集群進(jìn)行任務(wù)調(diào)度分配資源,通過單元測(cè)試進(jìn)行仿真,實(shí)施是可行的。
在相同配置下,文中提出的ACO算法的工作負(fù)載比Swarm算法放置的NGINX服務(wù)器快大約20%,優(yōu)于原始調(diào)度算法。對(duì)于ACO算法,仍然有許多改進(jìn)空間,例如對(duì)NGINX服務(wù)器特定參數(shù)的引入,將使調(diào)度程序?qū)γ總€(gè)特定情況都能更好地工作。