劉禹燕,牛保寧
(太原理工大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,太原 030024)
平臺(tái)即服務(wù)PaaS(Platform as a service)是將系統(tǒng)作為一種服務(wù)提供的商業(yè)模式,提供應(yīng)用程序的開(kāi)發(fā)和運(yùn)行環(huán)境.為了提高資源利用率,PaaS提供的平臺(tái)并非與真實(shí)物理主機(jī)一一對(duì)應(yīng),而是在一個(gè)或多個(gè)物理主機(jī)上構(gòu)建多個(gè)虛擬機(jī),向用戶提供平臺(tái)服務(wù).因此PaaS的實(shí)質(zhì)是將物理資源虛擬化,形成一個(gè)大型分布式系統(tǒng),虛擬化產(chǎn)生的每一個(gè)虛擬平臺(tái)都是云端的分布式系統(tǒng)中的獨(dú)立終端.
云計(jì)算的任何服務(wù)都必不可少的需要通過(guò)數(shù)據(jù)傳輸實(shí)現(xiàn),與磁盤(pán)、網(wǎng)卡等物理資源的頻繁交互帶來(lái)的I/O瓶頸[1-3]是云計(jì)算系統(tǒng)面臨的挑戰(zhàn).比如大量的磁盤(pán)讀寫(xiě)和網(wǎng)絡(luò)訪問(wèn),在原本直接抵達(dá)物理資源的應(yīng)用程序之下添加一層虛擬化監(jiān)控器管理層,使得應(yīng)用程序必須經(jīng)過(guò)客戶機(jī)操作系統(tǒng)和虛擬化監(jiān)控器的多層管理,這期間勢(shì)必增加了響應(yīng)時(shí)間上的延遲和性能上的過(guò)多開(kāi)銷(xiāo).以常見(jiàn)的虛擬化平臺(tái)KVM為例,未虛擬化前,應(yīng)用程序的網(wǎng)絡(luò)數(shù)據(jù)包經(jīng)由內(nèi)核TCP/IP協(xié)議封裝,調(diào)用網(wǎng)絡(luò)驅(qū)動(dòng)程序發(fā)送至網(wǎng)絡(luò)設(shè)備,完成本機(jī)網(wǎng)絡(luò)數(shù)據(jù)發(fā)送.KVM虛擬化后,虛擬機(jī)應(yīng)用程序的網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求經(jīng)過(guò)虛擬機(jī)內(nèi)核TCP/IP協(xié)議封裝,調(diào)用虛擬機(jī)網(wǎng)絡(luò)驅(qū)動(dòng)程序發(fā)送至虛擬網(wǎng)卡,然后產(chǎn)生虛擬中斷通知宿主機(jī)有數(shù)據(jù)要進(jìn)行發(fā)送,宿主機(jī)接收中斷進(jìn)行處理,再經(jīng)過(guò)真實(shí)物理網(wǎng)卡進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)發(fā)送.這其中由虛擬機(jī)中斷而切換到宿主機(jī)處理的過(guò)程被稱為系統(tǒng)切換,而系統(tǒng)切換需要占用大量CPU資源來(lái)保存上下文,如保存寄存器狀態(tài)、隊(duì)列上鎖、更新隊(duì)列等.當(dāng)有海量數(shù)據(jù)包發(fā)送,就需要進(jìn)行多次系統(tǒng)切換,造成CPU資源的浪費(fèi),也是虛擬化造成巨大開(kāi)銷(xiāo)的來(lái)源之一.因此如何減少系統(tǒng)切換開(kāi)銷(xiāo)、提升系統(tǒng)I/O性能、快速響應(yīng)請(qǐng)求、提高用戶體驗(yàn)是虛擬化技術(shù)需要解決的問(wèn)題.
本文基于KVM虛擬化平臺(tái),借助半虛擬化驅(qū)動(dòng)框架Virtio改進(jìn)virtio-net網(wǎng)絡(luò)模塊請(qǐng)求響應(yīng)的執(zhí)行流程.通過(guò)分析網(wǎng)絡(luò)請(qǐng)求從虛擬客戶機(jī)到宿主機(jī)的傳輸流程,我們發(fā)現(xiàn)每個(gè)請(qǐng)求都先要先經(jīng)過(guò)前端驅(qū)動(dòng)逐一處理,置于共享通道,并引起系統(tǒng)切換,接著轉(zhuǎn)為后端接收,后端接口在接收宿主機(jī)的請(qǐng)求時(shí),又采用逐一處理逐一通知的同步方式.對(duì)于每個(gè)請(qǐng)求都需要占用CPU時(shí)間進(jìn)行進(jìn)入共享通道,系統(tǒng)切換,接收請(qǐng)求,處理請(qǐng)求,處理完畢后保存上下文再次進(jìn)行系統(tǒng)切換.大量的請(qǐng)求導(dǎo)致頻繁的通知和系統(tǒng)切換,占用大量的CPU時(shí)間,造成系統(tǒng)性能下降.針對(duì)這一問(wèn)題,我們嘗試先將前端的多個(gè)請(qǐng)求聚合后再放置于共享通道,而后端則采用逐一處理,多次通知合并為一次通知的異步方式,從流程上多方面同步聚合以減少系統(tǒng)切換的開(kāi)銷(xiāo),把節(jié)省的CPU時(shí)間用于接收更多的網(wǎng)絡(luò)請(qǐng)求以及處理請(qǐng)求本身.
基于以上設(shè)想,本文提出基于virtio-net網(wǎng)絡(luò)模塊雙端的優(yōu)化方法TAM(two-end aggregation method),前后端分別加大工作量,批量聚合處理后再移交對(duì)應(yīng)端,減少雙端交互造成的系統(tǒng)切換.經(jīng)過(guò)實(shí)驗(yàn)測(cè)試,該方法首先使后端接收到統(tǒng)一聚合后的請(qǐng)求,減少前端逐一傳輸造成的大量開(kāi)銷(xiāo),隨后減少后端逐一返回請(qǐng)求通知前端造成的頻繁的上下文保存和系統(tǒng)切換的開(kāi)銷(xiāo),提高平臺(tái)的數(shù)據(jù)吞吐量和每秒處理事務(wù)數(shù),減少端到端響應(yīng)時(shí)間.
本文內(nèi)容及結(jié)構(gòu)如下:第二節(jié)概述相關(guān)工作.第三節(jié)介紹相關(guān)背景知識(shí).第四節(jié)對(duì)KVM的Virtio標(biāo)準(zhǔn)框架處理網(wǎng)絡(luò)請(qǐng)求的流程進(jìn)行性能瓶頸分析.第五節(jié)對(duì)流程進(jìn)行優(yōu)化,詳細(xì)介紹TAM,并分析該方法下請(qǐng)求的傳輸路徑.第六節(jié)對(duì)優(yōu)化方法進(jìn)行實(shí)驗(yàn)測(cè)試,并分析實(shí)驗(yàn)結(jié)果.第七節(jié)總結(jié)全文并提出下一步研究工作.
當(dāng)虛擬客戶機(jī)操作系統(tǒng)執(zhí)行敏感指令時(shí),為了保證系統(tǒng)安全,需要將控制權(quán)交給KVM,通過(guò)位于宿主機(jī)的Qemu軟件模擬出物理硬件的行為,保存和恢復(fù)寄存器狀態(tài)等,最終將執(zhí)行結(jié)果返回,客戶機(jī)操作系統(tǒng)再次獲得控制權(quán),這樣的系統(tǒng)級(jí)上下文切換會(huì)造成大量的開(kāi)銷(xiāo).為了提高系統(tǒng)性能,我們希望盡可能減少系統(tǒng)級(jí)上下文切換所帶來(lái)的開(kāi)銷(xiāo),現(xiàn)有的解決方法分別從指令層和算法層兩個(gè)方面進(jìn)行優(yōu)化.
在指令層優(yōu)化方面,BinBin Zhang等人[4]通過(guò)合并客戶機(jī)操作系統(tǒng)中的連續(xù)I/O指令,降低虛擬機(jī)的時(shí)鐘中斷頻率,從而降低系統(tǒng)切換的開(kāi)銷(xiāo),提高系統(tǒng)性能.A.Gordon 等人[5]提出ELI(Exit-Less Interrupt)方法,通過(guò)將宿主機(jī)從中斷處理路徑中移除減少了KVM虛擬機(jī)管理層處理的中斷數(shù)量,使網(wǎng)絡(luò)數(shù)據(jù)吞吐量產(chǎn)生顯著的提升,使I/O設(shè)備的性能達(dá)到接近原生設(shè)備的效果.本文方法從內(nèi)核的執(zhí)行流程角度分析,在算法層進(jìn)行路徑的優(yōu)化.
在算法優(yōu)化方面,Shuxin Cheng等人[6]提出AHC (Adaptive Hypercall Coalescing) 算法,在嵌入式ARM環(huán)境下,對(duì)半虛擬化驅(qū)動(dòng)的前端處理網(wǎng)絡(luò)請(qǐng)求的流程進(jìn)行優(yōu)化,在發(fā)送網(wǎng)絡(luò)請(qǐng)求時(shí)加入計(jì)時(shí)器,以時(shí)間為判斷標(biāo)準(zhǔn),在一定時(shí)間內(nèi)將待發(fā)送的請(qǐng)求聚合,提高了請(qǐng)求處理效率,減少了上下文切換代價(jià).由于該方法只考慮到半虛擬化驅(qū)動(dòng)的前端,且只有在網(wǎng)絡(luò)I/O請(qǐng)求密集的場(chǎng)景下具有良好的優(yōu)化效果,在網(wǎng)絡(luò)I/O請(qǐng)求稀疏的情況下,由于計(jì)時(shí)器的緣故,無(wú)法充分利用CPU資源,優(yōu)化方法的性能反而會(huì)降低.本文的方法在Intel X86體系架構(gòu)環(huán)境下,對(duì)半虛擬化驅(qū)動(dòng)的前后端分別進(jìn)行了優(yōu)化處理,并且不依賴于計(jì)時(shí)器,只與真實(shí)網(wǎng)絡(luò)請(qǐng)求相關(guān),因此在網(wǎng)絡(luò)I/O密集的情況下有良好的優(yōu)化效果,在網(wǎng)絡(luò)請(qǐng)求稀疏的情況下也不會(huì)影響性能,
此外一些基于Xen虛擬化平臺(tái)的一些解決方法也可以為KVM的優(yōu)化提供方向,M.Bourguiba和S.R.Thakur等人[7-9]基于Xen[10]實(shí)現(xiàn)網(wǎng)絡(luò) I/O 虛擬化模型,并提出數(shù)據(jù)包聚合方法,提升了網(wǎng)絡(luò) I/O 虛擬化的性能與可擴(kuò)展性.數(shù)據(jù)包聚合*https://en.wikipedia.org/w/index.php?title=Packet_aggregation&oldid=390003240.是為了減少每個(gè)數(shù)據(jù)包的傳輸開(kāi)銷(xiāo)將多個(gè)數(shù)據(jù)包組合進(jìn)一個(gè)傳輸單元的過(guò)程,當(dāng)過(guò)多的數(shù)據(jù)包消耗大部分CPU時(shí)鐘而每個(gè)數(shù)據(jù)包都相對(duì)較小時(shí),這種方法是有效的.本文的方法也參考數(shù)據(jù)包聚合的思路,將其應(yīng)用到半虛擬化驅(qū)動(dòng)前后端對(duì)數(shù)據(jù)包的處理上.
在虛擬平臺(tái)后端的優(yōu)化上,李家祥等人[11]將Xen后端驅(qū)動(dòng)中負(fù)責(zé)處理請(qǐng)求轉(zhuǎn)發(fā)的單tasklet改進(jìn)為多tasklet并行,提高數(shù)據(jù)包轉(zhuǎn)發(fā)的效率,從而提高整個(gè)網(wǎng)絡(luò)的吞吐率.本文的方法基于KVM半虛擬化驅(qū)動(dòng)框架Virtio前后兩端,雖然沒(méi)有進(jìn)行多任務(wù)并行,但是對(duì)每一端單任務(wù)處理的優(yōu)化使得資源得到最大化利用.
Hypervisor是一種運(yùn)行在基礎(chǔ)物理服務(wù)器和操作系統(tǒng)之間的中間軟件層,可允許多個(gè)操作系統(tǒng)和應(yīng)用共享硬件.KVM是首個(gè)被集成到Linux內(nèi)核的hypervisor解決方案,與Xen不同的是,KVM采用具有高級(jí)指令的新處理器,硬件虛擬化擴(kuò)展(Intel VT)的X86平臺(tái).
Virtio是 KVM 虛擬環(huán)境下針對(duì)I/O虛擬化的最主要的一個(gè)通用框架,KVM使用半虛擬化框架Virtio前端后端驅(qū)動(dòng)模塊互相協(xié)作的方式,減少I(mǎi)/O操作時(shí)系統(tǒng)中斷和權(quán)限轉(zhuǎn)換所帶來(lái)的開(kāi)銷(xiāo),同時(shí)由于半虛擬化采用的數(shù)據(jù)描述符機(jī)制,用數(shù)據(jù)描述符來(lái)傳遞數(shù)據(jù)信息而不是進(jìn)行跨主機(jī)數(shù)據(jù)拷貝,使得數(shù)據(jù)讀寫(xiě)只發(fā)生在共享內(nèi)存區(qū)域,減少冗余的數(shù)據(jù)拷貝,使用Virtio的KVM網(wǎng)絡(luò)I/O性能有很大提升.
默認(rèn)的標(biāo)準(zhǔn)Virtio的后端處理程序處于宿主機(jī)的用戶空間,網(wǎng)絡(luò)I/O請(qǐng)求從虛擬客戶機(jī)經(jīng)過(guò)系統(tǒng)切換首先到達(dá)宿主機(jī)用戶空間Qemu后端,再陷入宿主機(jī)內(nèi)核,現(xiàn)有的Vhost方法將Virtio后端處理程序直接放置于宿主機(jī)的內(nèi)核中,這使得網(wǎng)絡(luò)I/O請(qǐng)求經(jīng)過(guò)系統(tǒng)切換到達(dá)宿主機(jī)時(shí),直接轉(zhuǎn)發(fā)給處于內(nèi)核的Vhost,省去請(qǐng)求在宿主機(jī)用戶空間轉(zhuǎn)發(fā)的過(guò)程,通過(guò)縮短數(shù)據(jù)傳輸路徑提升系統(tǒng)性能、減少響應(yīng)時(shí)間.
如圖1所示,Virtio由三部分構(gòu)成:前端驅(qū)動(dòng)程序、后端驅(qū)動(dòng)程序以及用于前后端進(jìn)行信息傳輸?shù)墓蚕硗ǖ?Virtio-net是虛擬客戶機(jī)與宿主機(jī)網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)那岸私涌?,本?jié)我們將分析前后端接口對(duì)網(wǎng)絡(luò)數(shù)據(jù)包的處理流程與性能瓶頸.
圖1 Virtio半虛擬化框架Fig.1 Virtio para-virtualization framework
Virtqueue是承載著大量buffer數(shù)據(jù)的隊(duì)列,Virtio前端驅(qū)動(dòng)程序通過(guò)Virtqueue緩沖池與后端交互,把buffer插入隊(duì)列交給后端實(shí)現(xiàn)數(shù)據(jù)傳輸,其中buffer數(shù)據(jù)是以地址-長(zhǎng)度為格式的散集列表(scatter-gather)的形式存儲(chǔ)的.Virtio_ring是Virtio傳輸機(jī)制的具體實(shí)現(xiàn),ring buffers是數(shù)據(jù)傳輸?shù)妮d體.Virtio_ring包含3部分:描述符數(shù)組(descriptor table)用于存儲(chǔ)一些關(guān)聯(lián)的描述符,每個(gè)描述符都是一個(gè)對(duì)buffer的描述,包含一個(gè)address/length的配對(duì).可用的ring(available ring)用于虛擬客戶機(jī)端表示哪些描述符是可用的或者待處理的請(qǐng)求.使用過(guò)的ring(used ring)用于宿主機(jī)端表示哪些描述符是已經(jīng)處理的請(qǐng)求.
設(shè)備啟動(dòng)后,首先加載前端網(wǎng)絡(luò)驅(qū)動(dòng),調(diào)用Virtio_dev_probe()進(jìn)行Virtio設(shè)備識(shí)別、創(chuàng)建與初始化,其中find_vqs()創(chuàng)建一個(gè)與queue關(guān)聯(lián)的結(jié)構(gòu)體Vring,網(wǎng)絡(luò)設(shè)備有2個(gè)Virtqueue,分別用于發(fā)送和接收數(shù)據(jù)包.
假設(shè)虛擬客戶機(jī)發(fā)起一個(gè)網(wǎng)絡(luò)I/O請(qǐng)求,virtio傳輸方式可見(jiàn)圖2,前后端工作的具體流程如下:
1.虛擬客戶機(jī)通過(guò)Virtio前端接口發(fā)送buffer數(shù)據(jù)包
a) 使用add_buf(),把buffer添加到隊(duì)列描述符表中,填充addr,len,flags
b) 更新available ring的head,index信息
c) 調(diào)用kick()進(jìn)行超級(jí)調(diào)用,將Virtqueue index寫(xiě)入到Queue Notify寄存器,產(chǎn)生中斷通知宿主機(jī)
d) 虛擬客戶機(jī)保存寄存器狀態(tài),交出控制權(quán),隨后系統(tǒng)切換到宿主機(jī).
2.宿主機(jī)通過(guò)Virtio后端接口接收buffer數(shù)據(jù)包
a) 接收到中斷通知后,陷入宿主機(jī)內(nèi)核,CPU從中斷控制器的寄存器讀取數(shù)據(jù)確認(rèn)中斷
b) 調(diào)用Virtqueue_pop()從隊(duì)列描述符表中找到available ring中的buffer并映射內(nèi)存
c) 從散集列表讀取buffer數(shù)據(jù)
d)Virtqueue_fill()更新ring[idx]字段id和len
e)Virtqueue_flush()更新Vring_used中的idx
f) 調(diào)用Virtio_notify()將ISR狀態(tài)位寫(xiě)入1,通知虛擬客戶機(jī)前端描述符已經(jīng)使用
g) 宿主機(jī)保存寄存器狀態(tài),虛擬客戶機(jī)得到控制權(quán).
圖2 Virtio前后端請(qǐng)求傳輸方式Fig.2 Request transmission between virtio front-end and back-end
通過(guò)分析Virtio-net前后端處理請(qǐng)求數(shù)據(jù)的流程,我們注意到Virtio后端驅(qū)動(dòng)在將網(wǎng)絡(luò)I/O請(qǐng)求從共享通道Virtqueue中取出后立即調(diào)用Virtio_notify()通知前端處理該請(qǐng)求,而通知函數(shù)分為兩個(gè)階段,封鎖隊(duì)列而后產(chǎn)生虛擬中斷,這個(gè)過(guò)程的開(kāi)銷(xiāo)不可忽視.執(zhí)行超級(jí)調(diào)用消耗的時(shí)間在響應(yīng)延遲中占了很大的比例,也占用了大量的CPU資源.因此我們需要謹(jǐn)慎調(diào)用通知函數(shù),在超級(jí)調(diào)用前,盡可能處理更多的請(qǐng)求以提高資源利用率.
對(duì)于高密集的網(wǎng)絡(luò)I/O請(qǐng)求場(chǎng)景,隊(duì)列中會(huì)有大量請(qǐng)求等待傳輸,如果每個(gè)請(qǐng)求都需要等待前一個(gè)請(qǐng)求處理完成并且超級(jí)調(diào)用通知前端,前端接收中斷取得請(qǐng)求結(jié)果,才可以得到處理,這樣無(wú)謂的等待不僅造成響應(yīng)時(shí)間的延遲,還會(huì)使得大量CPU資源耗費(fèi)在隊(duì)列上鎖、隊(duì)列更新、修改寄存器狀態(tài)、接收中斷等系統(tǒng)切換所需的開(kāi)銷(xiāo)上,我們希望可以節(jié)省這些開(kāi)銷(xiāo)用于接收和處理更多的I/O請(qǐng)求上.
根據(jù)上節(jié)對(duì)網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求I/O路徑的分析,可以知道,在網(wǎng)絡(luò)I/O虛擬化過(guò)程中,超級(jí)調(diào)用造成開(kāi)銷(xiāo)的比例最大,而無(wú)論網(wǎng)絡(luò)流量大小,每次I/O請(qǐng)求都需要通過(guò)超級(jí)調(diào)用進(jìn)行系統(tǒng)上下文切換和權(quán)限轉(zhuǎn)換以達(dá)到請(qǐng)求數(shù)據(jù)傳輸?shù)哪康?
我們?cè)O(shè)想通過(guò)減少超級(jí)調(diào)用的次數(shù)來(lái)減少系統(tǒng)上下文切換的次數(shù),從而減低CPU負(fù)載,在網(wǎng)絡(luò)I/O密集的場(chǎng)景下,每個(gè)請(qǐng)求都需要超級(jí)調(diào)用,批量請(qǐng)求產(chǎn)生的開(kāi)銷(xiāo)不可估量,為此我們考慮將多個(gè)請(qǐng)求的超級(jí)調(diào)用聚合為一個(gè).
根據(jù)這個(gè)設(shè)想,我們對(duì)Virtio前后端進(jìn)行改進(jìn),提出雙端聚合的優(yōu)化方法TAM,對(duì)于待傳輸?shù)木W(wǎng)絡(luò)數(shù)據(jù),前端將一個(gè)請(qǐng)求放入隊(duì)列后,并沒(méi)有立即調(diào)用hypercall通知后端,而是繼續(xù)判斷是否還有請(qǐng)求等待傳輸,以隊(duì)列大小1024為依據(jù),接收請(qǐng)求直到隊(duì)列滿,通知后端.后端在收到前端已將請(qǐng)求放入隊(duì)列的通知后,得到隊(duì)列控制權(quán),取出隊(duì)列中一個(gè)待處理請(qǐng)求后,同樣并沒(méi)有立即調(diào)用hypercall通知前端,而是處理完隊(duì)列中全部請(qǐng)求后調(diào)用一次超級(jí)調(diào)用,產(chǎn)生虛擬中斷通知前端,前端一次性讀取隊(duì)列中所有處理完畢的請(qǐng)求結(jié)果.通過(guò)控制超級(jí)調(diào)用通知對(duì)應(yīng)端的時(shí)刻,將批量到達(dá)的多個(gè)請(qǐng)求所需的多次超級(jí)調(diào)用聚合為一次再通知,節(jié)省超級(jí)調(diào)用后系統(tǒng)切換造成的開(kāi)銷(xiāo)和時(shí)間,使CPU有更多的時(shí)間處理數(shù)據(jù)傳輸本身,理論上可以提高數(shù)據(jù)吞吐量,減少響應(yīng)時(shí)間,降低CPU開(kāi)銷(xiāo).
我們基于virtio前后端網(wǎng)絡(luò)處理模塊,對(duì)前端發(fā)送函數(shù)和后端接收函數(shù)進(jìn)行優(yōu)化,在單獨(dú)處理的數(shù)據(jù)包外層增加while循環(huán),使得處理完畢的數(shù)據(jù)包不被立即通知給對(duì)端,具體算法偽碼如下.
算法1.前端聚合方法
輸入:待發(fā)送的數(shù)據(jù)包*skb,發(fā)送數(shù)據(jù)的網(wǎng)絡(luò)設(shè)備隊(duì)列net_queue,隊(duì)列狀態(tài)state,virtio發(fā)送隊(duì)列sq
①初始化:數(shù)據(jù)包入隊(duì)后隊(duì)列大小i
②while(i
③ skb入sq隊(duì)列
④ i=i+skb.len
⑤ 移向下一個(gè)skb
⑥}end while
⑦ 觸發(fā)中斷,通知后端
算法2.后端聚合方法
輸入:接收隊(duì)列vq,隊(duì)列元素&elem
①while(virtqueue_pop(vq,&elem)){
② handle the elem
③ 移向隊(duì)列下一個(gè)元素
④}end while
⑤觸發(fā)中斷,通知前端
由于TAM方法雙端處理流程優(yōu)化的基本思路相同,且本文相比現(xiàn)有方法增加了后端的優(yōu)化,圖3只列出后端的網(wǎng)絡(luò)請(qǐng)求處理過(guò)程:
該過(guò)程反應(yīng)了優(yōu)化后Virtio后端對(duì)網(wǎng)絡(luò)請(qǐng)求的處理,前端將要發(fā)送的數(shù)據(jù)放入Virtqueue后,調(diào)用Virtqueue_kick()通知后端,這個(gè)過(guò)程涉及一次系統(tǒng)上下文切換,接著后端收到中斷通知,調(diào)用virtio_net_receive接收數(shù)據(jù),我們判斷Virtqueue中是否還有請(qǐng)求需要處理,如果有,調(diào)用Virtqueue.pop()取出環(huán)中元素直到請(qǐng)求全部取出,如果沒(méi)有等待中的請(qǐng)求,則調(diào)用Virtqueue_notify()產(chǎn)生虛擬中斷通知前端處理后的結(jié)果,此時(shí)處理過(guò)的所有請(qǐng)求都已標(biāo)記為used,并不會(huì)造成丟失請(qǐng)求的問(wèn)題.
實(shí)驗(yàn)測(cè)試的硬件環(huán)境:Intel Xeon E7-4809 v2 1.9GHz處理器.軟件環(huán)境:宿主機(jī)Linux 4.7.0版本內(nèi)核,Qemu 1.2.50,虛擬客戶機(jī)Linux 4.6.1版本內(nèi)核.
圖3 TAM后端 I/O請(qǐng)求處理流程Fig.3 TAM back-end I/O requests workflow
實(shí)驗(yàn)設(shè)定請(qǐng)求隊(duì)列大小為1024字節(jié)進(jìn)行測(cè)試.
實(shí)驗(yàn)使用經(jīng)典的基準(zhǔn)測(cè)試程序Netperf和Ping對(duì)數(shù)據(jù)吞吐量、延時(shí)、TPS(每秒處理事務(wù)數(shù))進(jìn)行測(cè)試,同時(shí)對(duì)CPU開(kāi)銷(xiāo)也進(jìn)行了監(jiān)控測(cè)試.
每個(gè)實(shí)驗(yàn)進(jìn)行以下三種半虛擬化方法的對(duì)比測(cè)試:
1)AHC:文獻(xiàn)[6]的Virtio半虛擬化前端優(yōu)化方法
2)VHOST:已有的Virtio半虛擬化的后端優(yōu)化方法
3)TAM:本文的Virtio半虛擬化雙端聚合優(yōu)化方法
我們對(duì)上述三種方法使用Netperf進(jìn)行批量數(shù)據(jù)傳輸(bulk data transfer)模式的網(wǎng)絡(luò)性能測(cè)試.測(cè)試時(shí),宿主機(jī)作為Netserver服務(wù)端,虛擬機(jī)作為Netperf客戶端,客戶端發(fā)送批量的TCP數(shù)據(jù)分組以確定數(shù)據(jù)傳輸過(guò)程中的數(shù)據(jù)吞吐量.
圖4 數(shù)據(jù)吞吐量測(cè)試結(jié)果Fig.4 Test results of data throughput
圖4是在不同數(shù)據(jù)包大小傳輸?shù)那闆r下數(shù)據(jù)吞吐量的測(cè)試結(jié)果.TAM方法數(shù)據(jù)包大小在64 bytes到32K bytes時(shí)數(shù)據(jù)吞吐量基本穩(wěn)定在350左右,Vhost方法數(shù)據(jù)吞吐量?jī)H250左右,TAM方法數(shù)據(jù)吞吐量相比AHC提高5.76%,這是由于相比AHC,TAM方法的后端是將數(shù)據(jù)包請(qǐng)求聚合后才返回響應(yīng),節(jié)省了每個(gè)數(shù)據(jù)包通知的開(kāi)銷(xiāo)以及系統(tǒng)切換的開(kāi)銷(xiāo),使得CPU時(shí)鐘可以處理更多的數(shù)據(jù)流量傳輸.
我們對(duì)上述三種方法使用Ping進(jìn)行不同大小數(shù)據(jù)包傳輸?shù)难訒r(shí)測(cè)試.測(cè)試時(shí),虛擬機(jī)作為Ping發(fā)送端發(fā)送數(shù)據(jù)包,宿主機(jī)作為Ping接收端,收到數(shù)據(jù)包后返回一個(gè)同樣大小的數(shù)據(jù)包來(lái)確定兩臺(tái)主機(jī)是否連接相通,時(shí)延是多少.
圖5是在不同數(shù)據(jù)包大小傳輸?shù)那闆r下,TCP延時(shí)的測(cè)試結(jié)果.AHC方法響應(yīng)延時(shí)不太穩(wěn)定,但總體看來(lái),延時(shí)隨著傳輸數(shù)據(jù)量的增大而增大,這是由于數(shù)據(jù)拷貝量的增加和系統(tǒng)之間的切換造成的.可以看到,使用Vhost后端優(yōu)化處理后有一定的效果,這是由于縮短請(qǐng)求的響應(yīng)路徑,系統(tǒng)切換到宿主機(jī)后直接進(jìn)入內(nèi)核處理,節(jié)省了時(shí)間.由于TAM方法縮短的時(shí)間是系統(tǒng)切換的時(shí)間,對(duì)于每個(gè)請(qǐng)求,系統(tǒng)切換的時(shí)間遠(yuǎn)大于請(qǐng)求在宿主機(jī)用戶空間轉(zhuǎn)發(fā)的時(shí)間,所以TAM方法比Vhost方法時(shí)間更短.而相比AHC,時(shí)間上的減少則是雙端同時(shí)優(yōu)化改進(jìn)起到了作用.
圖5 延時(shí)測(cè)試結(jié)果Fig.5 Test results of delay
我們使用Netperf進(jìn)行請(qǐng)求/應(yīng)答(request/response)模式的網(wǎng)絡(luò)性能測(cè)試,測(cè)試時(shí)宿主機(jī)作為Netserver服務(wù)端,虛擬機(jī)作為Netperf客戶端,客戶端向服務(wù)端發(fā)送小的查詢分組,服務(wù)端接收到請(qǐng)求,經(jīng)處理后返回大的結(jié)果數(shù)據(jù).
6.4.1 一次連接多次請(qǐng)求TCP_RR
圖6是在小數(shù)據(jù)包傳輸?shù)那闆r下,TCP_RR的TPS測(cè)試結(jié)果.Vhost由于后端直接經(jīng)內(nèi)核轉(zhuǎn)發(fā)請(qǐng)求,縮短了路徑,節(jié)省了一定資源用于處理其他請(qǐng)求,TPS有一定提升,然而對(duì)于小數(shù)據(jù)包來(lái)說(shuō),頻繁的系統(tǒng)切換才是真正的痛點(diǎn),TAM方法雖然處于用戶空間,但該方法在問(wèn)題瓶頸點(diǎn)進(jìn)行優(yōu)化,減少超級(jí)調(diào)用,因此比Vhost方法效果更優(yōu).
圖6 小數(shù)據(jù)包TCP_RR測(cè)試結(jié)果Fig.6 Test results of small packages on TCP_RR
圖7是在大數(shù)據(jù)包傳輸?shù)那闆r下,TCP_RR的TPS測(cè)試結(jié)果.可以看到,單獨(dú)優(yōu)化前端的AHC和單獨(dú)優(yōu)化后端的Vhost基本重合,而TAM方法有少量提升,這是由于隊(duì)列大小為1024,在傳輸大于1024的數(shù)據(jù)包時(shí),TAM方法不能達(dá)到很好的利用,因此結(jié)果與其他兩方法相近,效果不明顯.
6.4.2 多次連接多次請(qǐng)求TCP_CRR
圖8是在小數(shù)據(jù)包傳輸?shù)那闆r下,TCP_CRR的TPS測(cè)試結(jié)果.總體來(lái)說(shuō),TAM方法以雙端為出發(fā)點(diǎn)減少系統(tǒng)切換次數(shù),達(dá)到比AHC和Vhost更高的TPS.
圖7 大數(shù)據(jù)包TCP_RR測(cè)試結(jié)果Fig.7 Test results of big packages on TCP_RR
圖8 小數(shù)據(jù)包TCP_CRR測(cè)試結(jié)果Fig.8 Test results of small packages on TCP_CRR
圖9是在大數(shù)據(jù)包傳輸?shù)那闆r下,TCP_CRR的TPS測(cè)試結(jié)果.由于大于1024的數(shù)據(jù)包傳輸所需的必要的系統(tǒng)切換很難因TAM的聚合而減少,因此TPS提升很小.
圖9 大數(shù)據(jù)包TCP_CRR測(cè)試結(jié)果Fig.9 Test results of big packages on TCP_CRR
在使用netperf基準(zhǔn)測(cè)試程序進(jìn)行TCP_STREAM壓力測(cè)試的同時(shí),我們對(duì)作為netserver服務(wù)端的宿主機(jī)系統(tǒng)進(jìn)行了整體性能監(jiān)測(cè),監(jiān)測(cè)工具為vmstat.
表1 CPU開(kāi)銷(xiāo)
Table 1 CPU overhead
%wa%id%us%syincsTAM1325116637585430AHC73144187862104871
由表1可知,相比AHC方法,TAM方法減少了CPU等待I/O的時(shí)間wa,緩解I/O瓶頸,充分利用了CPU資源.此外,由于后端qemu工作量的集中機(jī)制,用戶CPU使用率us提高,且聚合減少了系統(tǒng)內(nèi)核切換的開(kāi)銷(xiāo),系統(tǒng)CPU使用率sy有所減少.每秒中斷次數(shù)in有一定減少,cs響應(yīng)也有所減少.因此看出,雙端聚合有一定成效,但cs依然很高,原因是在批量網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)臏y(cè)試下,傳輸隊(duì)列大小設(shè)定相對(duì)較小的緣故.
本文針對(duì)虛擬化環(huán)境KVM中網(wǎng)絡(luò)I/O性能的優(yōu)化進(jìn)行研究,通過(guò)分析KVM半虛擬化框架Virtio處理網(wǎng)絡(luò)I/O請(qǐng)求的流程,得出占用CPU資源最多的場(chǎng)景是I/O請(qǐng)求數(shù)據(jù)轉(zhuǎn)換時(shí)超級(jí)調(diào)用導(dǎo)致的系統(tǒng)切換,造成性能瓶頸.與現(xiàn)有的基于半虛擬化前端進(jìn)行優(yōu)化的解決方法不同,本文提出一種雙端聚合方法TAM,該方法分別以Virtio前后端為基礎(chǔ),改進(jìn)默認(rèn)的后端Virtio-net處理網(wǎng)絡(luò)請(qǐng)求的方式優(yōu)化AHC前端網(wǎng)絡(luò)請(qǐng)求處理方式,前端將待發(fā)送的網(wǎng)絡(luò)請(qǐng)求聚合后統(tǒng)一通知后端,后端將共享通道隊(duì)列描述符列表中的可用請(qǐng)求逐一處理后統(tǒng)一通知前端,將多次超級(jí)調(diào)用的開(kāi)銷(xiāo)合并為一次,減少系統(tǒng)切換次數(shù)和權(quán)限轉(zhuǎn)換次數(shù),降低CPU開(kāi)銷(xiāo),提升系統(tǒng)性能.實(shí)驗(yàn)測(cè)試表明,使用TAM方法的Virtio網(wǎng)絡(luò)模型,數(shù)據(jù)吞吐量相比只優(yōu)化前端的AHC方法提高5.76%,TCP_RR的每秒處理事務(wù)數(shù)提高4.39%,TCP_CRR的每秒處理事務(wù)數(shù)提高4.32%,延時(shí)減少46.2%.接下來(lái)的工作,我們將測(cè)試并選取合適的請(qǐng)求聚合大小即傳輸隊(duì)列大小以平衡系統(tǒng)性能和每個(gè)請(qǐng)求的等待時(shí)間.
[1] Caulfield A M,Mollov T I,Eisner L A,et al.Providing safe,user space access to fast,solid state disks[J].Acm Sigplan Notices,2012,40(1):387-400.
[2] Dall C,Nieh J.KVM/ARM: the design and implementation of the linux ARM hypervisor[J].Acm Sigplan Notices,2014,42(1):333-348.
[3] Har′El N,Gordon A,Landau A,et al.Efficient and scalable paravirtual I/O system[C].Usenix Annual Technical Conference(USENIX ATC′13),USENIX Association,2013:231-242.
[4] Rasmusson L,Corcoran D.Performance overhead of KVM on Linux 3.9 on ARM cortex-a15[J].Acm Sigbed Review,2014,11(2):32-38.
[5] Gordon A,Amit N,Har′El N,et al.ELI: bare-metal performance for I/O virtualization[J].Acm Sigplan Notices,2012,47(4):411-422.
[6] Cheng Shu-xin,Yao Jian-guo,Hu Fei.Optimizing network I/O performance through adaptive hypercall coalescing in embedded virtualization[C].Proceedings of the 30th ACM/SIGAPP Symposium on Applied Computing (SAC 2015),Salamanca,Spain,2015.
[7] Nordal A,Kvalnes,,Johansen D.Paravirtualizing TCP[C].Proceedings of the 6th International Workshop on Virtualization Technologies in Distributed Computing Date,ACM(VTDC′12),2012:3-10.
[8] Bourguiba M,Haddadou K,Pujolle G.Packet aggregation based network I/O virtualization for cloud computing[J].Computer Communications(COMPUT COMMUN),2012,35(3):309-319.
[9] Thakur S R,Goudar R M.Improving network I/O virtualization performance of xen hypervisor[J].International Journal of Engineering Trends & Technology(IJETT),2014,11(2):79-83.
[10] Abolfazli S,Sanaei Z,Ahmed E,et al.Cloud-based augmentation for mobile devices:motivation,taxonomies,and open challenges[J].IEEE Communications Surveys & Tutorials(IEEE COMMUN SURV TUT),2013,16(1):337-368.
[11] Li Jia-xiang.Research on optimization of xen network I/O performance [D].Wuhan:Huazhong University of Science and Technology,2013.
附中文參考文獻(xiàn):
[11] 李家祥.Xen虛擬機(jī)網(wǎng)絡(luò)I/O性能優(yōu)化研究[D].武漢:華中科技大學(xué),2013.