Kvm虛擬化性能測試與性能優化實踐

wKiom1kW1NWTtdnSAABvIoBICjU254.jpg

1.環境介紹

1.1測試簡介

本次測試是針對KVM虛擬化在CPU、內存、磁盤、網絡4大方面的全面性能測試與性能優化實踐,目的在於通過對比測試,找出最適合我們所使用的硬件與軟件架構的最佳優化配置,爲OpenStack實現更高的性能提供支持。

 

1.2 硬件環境介紹

本次測試中,我們將通過OpenStack平臺作爲虛擬機管理工具,並且所有的用於測試的虛擬機都均運行在同一臺物理機上

wKioL1kWyxDhqJ-PAAA4hIlzGck127.png


1.3 軟件環境介紹

下面介紹一下本次測試的主機的軟件環境:

wKioL1kWy1KgvU0mAAAxJvqW_yk695.png

以上就是本次KVM虛擬化測試所在主機的軟件環境,其中值得注意的是KvmLibvirt的版本。


1.4 虛擬機測試用例

爲了保證測試的科學嚴謹性,我們將選用同等規格的KVM虛擬機,在openstack中我們統一選用m1.small規格,即1vCPU2G內存、系統磁盤爲20G

wKiom1kWy4rxqPZeAAAJZNmVK0g654.png

我們的虛擬機統一通過openstack來做創建、終止等操作,這樣既保證了創建等操作不會因爲人爲操作失誤而產生偏差,同時也使本次測試的結果爲OpenStackHypervisor選型提供參考。


2. CPU部分

在虛擬化技術的發展過程中,我們可以看到也是CPU技術飛速發展的階段,同時,這也說明了虛擬化對於CPU的要求是硬性的,即很難通過更加優秀的策略和算法來大量地提升性能。

但是,在這個追求高效低碳的時代,性能上的一點點提升都是值得我們去努力探索的。

 

2.1 虛擬機CPU性能將損失多少?

KVM虛擬化的CPU使用機制中,虛擬機的vCPU在虛擬機內部實現的各種調度對於宿主機的CPU是透明,每個vCPU對於物理CPU來說僅僅相當於一個進程,通過不同虛擬機不同優先級的情況來將CPU的核心分配給vCPU獨佔使用。

這樣,我們不禁想知道,在KVM虛擬機中使用vCPU和宿主機中使用物理CPU,中間的性能損失有多少呢?

 

2.1.1 環境介紹

下面,我們將利用一個由C++編寫的“找出1-1千萬以內的質數”程序,在虛擬機和宿主機中分別進行測試,利用time工具查看他們分別需要多少的時間,以此來判斷CPU的性能。

值得注意的是,我們的虛擬機分配了1vCPU,但是由於我們編寫的測試程序是單線程的,所以在宿主機和虛擬機中運行都只能使用到1CPU核心,保證了測試的嚴謹性。

並且,該程序不會因爲內存問題而使得宿主機和虛擬機的測試產生偏差,因爲對於改程序來說其需要的內存在虛擬機上也是完全滿足的。

以下是測試所用程序的源碼:

#include<iostream>
#include<math.h>
using namespace std;
static int num=100000000;
int main(){
 
       bool *array=new bool[num+1];
       array[0]=false;
       array[1]=false;
       for(int i=2;i<=num;i++) array[i]=true;
       int b=int(pow(num,0.5))+1;
       int index=0;
       for(int j=2;j<=b;j++){
                index=2*j;
                while(index<=num){
                        array[index]=false;
                        index+=j;
                }
       }
       delete array;
       cout<<endl<<"===========Done!==========="<<endl;
       return 0;
}


2.1.2 測試分析

爲了使數據更加有參考意義,我們將分別測試找出不同數量的質數,如1百萬以內、1千萬以內、1億以內的質數。

首先,我們在虛擬機中運行測試程序:

wKioL1kWzA6A7LlTAAASHlexk1Q905.png

接下來,我們在宿主機運行測試程序:

wKiom1kWzBzBZOb5AAASmE_SVzE250.png

以上的測試數據都經過了3次測試,並且取平均值,以保證測試數據的可靠性。我們將以上兩部分的測試結果彙總如下:

wKiom1kWzEKzxhH_AAAqXm6Hv6Y683.png

從以上數據我們可以看到在1百萬和1千萬兩次測試中,虛擬機和宿主機的性能幾乎是沒有損失的,但是到了1億數據測試時,在性能表現上出現了巨大的變化,針對這樣的結果,我們在虛擬中利用vmstat監控CPU的狀態。

wKiom1kWzF6iBCsmAAAp8jx3iz4678.png

上圖是虛擬機中執行1千萬數據測試的狀態,在查找過程中,虛擬機CPU使用率大約在30%-50%CPU沒有達到滿負荷。

wKiom1kWzHiTeNE5AAAg4bb5t4Y096.png

上圖是虛擬機執行1億數據測試的vmstat狀態,我們可以看到虛擬機CPU持續地保持在100%的負載,此時則說明該測試已經到了虛擬機CPU的性能天花板,這樣的性能表現不是因爲宿主機的資源搶佔造成的。

爲了證明虛擬機在1億數據量時的性能下降不是宿主機資源搶佔造成的,我們將同時在宿主機和虛擬機上運行測試程序。

以下是宿主機和虛擬機同時運行測試程序的測試數據:

wKiom1kWzKOjemZ4AAAz0ouuO0E881.png

從以上數據可知,宿主機與虛擬機同時運行時的表現和單獨運行幾乎是沒有偏差的,而宿主機上的CPU爲什麼沒有不會像虛擬機中那樣滿負荷呢?可能是由於CPU自身的調度機制,這裏不深究。

由於1億的數據量對於單vCPU的虛擬機來說已經到了性能瓶頸,不能對比體現虛擬機與宿主機使用CPU的性能損耗,故不能作爲對比的數據。

wKioL1kWzM2TR8AhAAAyvlp1w1k577.png

wKioL1kWzPTS0NV8AABCsJEWuxA305.png

我們將以上的數據彙總並生成條形圖,可以看到KVM虛擬機對於物理機的CPU損失非常小,這也是完全虛擬化最大的優點之一。


3. 內存部分

近年來的虛擬化技術的發展中,針對內存方面的探索明顯比其他方面要多,因爲內存往往決定了虛擬機的運行性能,當宿主機需要使用swap交換分區來爲虛擬機分配內存的時候,則虛擬機的性能將急速下降。

下面我們針對應用面最廣的KSM內存頁共享和HugePage大頁技術來進行性能測試分析和優化的實踐。

 

3.1 虛擬機內存性能將損失多少?

3.1.1 環境介紹

在我們選用一款虛擬化產品之前,我們最希望瞭解的是虛擬機中的CPU與內存跟物理機相比,性能將損失多少,其損失的性能是我們所能接受的嗎?

針對這樣的問題,我們將對虛擬機和宿主機進行內存測試,我們採用了一款功能強大的內存質量測試工具:memtester。你可以指定要用於測試的內存大小,例如100Mmemtester會從可用內存中抓取100M內存,進行各項測試運算,包括隨機值寫入、乘法、除法、異或比較、與或運算等等。我們利用time工具統計內存測試完成的時間,通過比較時間來看內存性能。

 

3.1.2 測試分析

首先,我們需要在測試用虛擬機和宿主機中分別安裝memtester軟件:

# apt-get install memtester

我們分別抓取10M100M1000M的內存作爲測試的內存大小,每個測試重複測試3次,取平均值。

以下是虛擬機中的測試數據:

wKioL1kWzZOieWlrAAAVc0sf_68591.png

以相同的方法在宿主機上測試,得到如下數據:

wKiom1kWzaKQEoSTAAAUyHbTm_Q259.png

將虛擬機和宿主機的測試數據彙總,得到如下表格,完成全部內存測試項目用時最少的表明性能越好。

wKiom1kWzcjxIPVpAAA3JHK6CAw721.png

wKioL1kWzfbgJxO0AAA1vA14dks982.png

以上是由測試數據生成的圖表,我們可以看到,對於虛擬機來說,的確會對內存產生部分的性能損耗,對於KVM虛擬化來說,CPU的性能是十分微小的,因爲KVM完全虛擬機的內部機制決定了它在CPU方面的表現,但是KVM的內存調度並沒有太大的改進,完全虛擬化的內存調度不需要通過OS,而是直接由Hypervisor直接從內存中獲取,這樣的機制相比半虛擬化有部分的性能提升。

本次內存性能測試中,我們的結論是,KVM虛擬化產品的內存與物理機內存相比,其性能損失大約在10%以下,這樣的表現對於虛擬化產品來說是比較出色的。


3.2 到底要不要開啓KSM頁共享?

3.2.1 環境介紹

KSMKernelSamepage Merging)即內存頁共享機制。頁共享早已有之,linux中稱之爲COW(copyon write)Linux 2.6.32內核之後又引入了KSMKSM的主要特性是可以讓內核查找內存中完全相同的內存頁然後將他們合併起來,並將合併後的內存頁打上COW標記。KSMKVM環境有很重要的意義,當KVM上運行許多相同系統的虛擬機時,虛擬機之間將有許多內存頁是完全相同的,特別是只讀的加載在內存中的內核代碼頁,完全可以在虛擬機之間共享,從而減少虛擬機佔用的內存資源,從而使得宿主機可以同時運行更多的虛擬機。

我們在宿主機上運行10個虛擬機,統一採用OpenStack中的Small硬件規格,在沒有開啓KSM的情況下,我們監控宿主機CPU的負載情況,之後開啓KSM功能,並設置KSM持續刷新,同時繼續監控宿主機CPU負載,以此對比得出KSM功能對CPU負載會有多大的影響。

 

3.2.2 測試分析

本次測試我們使用sar工具來實時查看宿主機的CPU負載信息,當10臺虛擬機完全啓動之後,我們在宿主機上運行一段時間的sar,抓取沒有開啓KSMCPU負載,取平均值。

首先,我們需要在OpenStack中利用Dashboard圖形化界面從同一個鏡像文件啓動10臺虛擬機實例。

wKioL1kWziej2qIqAAEeM2-5-RY002.png

全部的虛擬機實例啓動完成之後,我們使用sar工具每個2秒一次CPU負載信息,抓取20次,將當前宿主機CPU空閒率取平均值。

wKioL1kWzqbSCCsJAAA5fGDJ7IQ397.png

最後得出,當前宿主機CPU空閒率爲96.86%

 

接下來,我們開啓KSM功能,在Debian中默認沒有開啓KSM功能,需要我們手動開啓:

# echo 1 > /sys/kernel/mm/ksm/run

/sys/kernel/mm/ksm/目錄就是KSM模塊所在的位置,針對KSM的所有設置都只能在這裏把數據echo進去,/sys/kernel/mm/ksm/run是用於控制是否開啓KSM功能的文件,“1”表示開啓,“0”表示關閉。

同時,/sys/kernel/mm/ksm/目錄下還有很多其他的用於精細化配置的文件,例如/sys/kernel/mm/ksm/sleep_millisecs,此文件用於指定KSM查找相同內存頁的時間間隔。

爲了測試出KSM對於宿主機CPU負載的影響,我們將KSM查找相同內存頁的時間間隔設置爲“0”,即KSM會不停地在內存中查找有沒有相同的內存頁。設置方法如下:

# echo 0 >/sys/kernel/mm/ksm/sleep_millisecs

設置完成後,我們使用sar監控CPU負載的變化:

wKiom1kWzsLRIL80AAAz2R1efKk682.png

經過計算,當前宿主機CPU空閒率爲95.12%

以下是關閉KSM和開啓KSM情況下的CPU負載圖表,這樣能使我們更加直觀地看出對比。

wKioL1kWzu6A2rYwAABRb2vwoA4125.png

我們可以得出,開啓KSM之後會比關閉KSMCPU負載高1.74%。但是這樣的數據是在宿主機的虛擬機數量較少,並且所有虛擬機都處於空閒狀態,所以真實環境下負載的提高是跟虛擬機以及業務有關的,根據官方數據,在生產環境下開啓KSM,其會佔用的CPU負載大概爲3%-10%

這是一個極限測試,但是在真實應用中,我們往往會根據宿主機的軟件硬件情況設置不同的時間間隔,儘量減少KSM對宿主機CPU負載的負擔,同時KSM項目組也在積極努力以使得KSM能佔用更少的CPU

 

3.2.3 優化實踐

做完以上的測試分析,新的問題馬上浮出了水面:我們到底要不要開啓KSM呢?

我們知道,KSM機制最根本的目的在於使得一個宿主機能儘可能多地運行更多的虛擬機。如果你的虛擬化架構需要運行儘量多的虛擬機,例如IDC商,那麼開啓KSM會是一個十分不錯的選擇;如果你更多的是追求虛擬機有更高的性能,內存不是你們的稀缺資源,並且不希望KSM加大了宿主機的負載,那麼請關閉KSM

對於OpenStack的應用來說,往往運算節點上運行着衆多由同一個鏡像啓動起來的虛擬機實例,這種情況開啓KSM是十分有利的,並且根據我們的測試,KSM對於宿主機的影響是比較輕微的,我們可以根據宿主機的CPU性能、內存大小、預計運行虛擬機數量來設置KSM查找相同內存頁的時間間隔,以此來控制KSM對宿主機的影響。

值得注意的是:國人對KSM做了進一步優化,發佈了UKSM(UltraKSM)項目,據說比KSM掃描更全面,掃描頁面速度更快,而且CPU佔用率更低,目前此項目已經能在FedoraUbuntu的源中使用。

 

3.3 使用Huge Page能帶來多少性能提升?

Huge Page,有人稱爲巨頁,也可以稱爲大頁。x86架構通常使用4K內存頁,但也有能力使用更大的內存頁,x86_32可以使用4MB內存頁,x86_64x86_32PAE可以使用2MB內存頁。

x86內存使用多級頁表結構,一般有三級:頁目錄表、頁表、頁。我們通過使用大頁,可以減少頁目錄表和頁表對內存的消耗。通過爲虛擬機提供大頁的後端內存,可以減少虛擬機消耗的內存並提高內存TLB(頁表緩存)命中率,從而提升KVM性能。

 

3.3.1 環境介紹

下面介紹一下測試環境。我們依然在hz188-139宿主機上進行全部的測試,虛擬機在OpenStack創建,規格爲m1.Small

我們首先在沒有配置HugePage的情況下,利用內存測試工具memtester對虛擬機中的內存進行測試,之後配置開啓HugePage大頁功能,再在虛擬機中做同樣的測試,之後彙總結果進行分析。

每個測試測試3次,取平均值。

以下是我們在宿主機上配置HugePage大頁的操作:

# mkdir /dev/hugepage

查看hugepage的相關內核參數:

# sysctl -a | grep -i huge 

wKiom1kWzw3i27BcAAAa-0JnX-U563.png

其中的“vm.nr_hugepages”參數是指用戶大頁的頁面數,在設置我們要開啓的大頁數之前,需要查看一下當前系統HugePage的大小:

# cat /proc/meminfo | grep -i huge

我們可以看到當前系統的大頁爲2M,而設置開啓大頁數量是一門大學問,因爲大頁是常駐內存的,我們要嚴謹地分析、合理地規劃,確保不會影響宿主機系統的性能,同時又讓KVM能最大限度地使用大頁。

我們將要設置的參數寫入到sysctl.conf文件中:

# vi /etc/sysctl.conf

# sysctl -p | grep huge

接下來掛載hugepage虛擬文件系統:

# mount -t hugetlbfs hugetlbfs/dev/hugepage

爲了使hugepage的設置開機自啓動,我們需要把掛載信息寫入到fatab中。

當我們需要創建KVM虛擬機的時候,我們需要手動地用“-mem-path”參數來指定hugepage虛擬文件系統的地址,讓KVM通過hugepage獲取內存。

在我們可以在/proc/meminfo中查看“HugePages_Total”和“HugePages_Free”項,可以直觀地看到當前宿主機上hugepage的使用情況。

 

3.3.2 測試分析

我們的測試將利用memtester作爲測試工具,在虛擬機內部,當我們需要使用內存時,KVM會通過一定的機制去申請獲取物理內存,而普通情況下換入換出的內存頁大小爲4K,當我們設置使用大頁之後,KVM虛擬機就會直接通過大頁來申請內存,這時的內存頁大小爲2MMemtester中的內存質量測試都會是一樣的,唯獨在申請內存及使用時,普通的方式和通過大頁的方式有所區別,所以我們可以通過完成memtester的時間作爲一個衡量的標尺。

以下是普通內存分配方式下的測試數據:

wKioL1kWzz2g3vPjAAAmWSbJV6M840.png

以下是Huge Page內存分配方式下的測試數據:

wKioL1kWz6Sw98Y6AAAoXCaq3-g666.png

下面,我們將以上的兩組數據彙總如下:

wKiom1kWz67wir5wAAA4n3JgZdM292.png

wKioL1kWz6_ABhR1AAA6oJEVric777.png


3.3.3 優化實踐

根據以上的測試數據,我們可以看到使用了HugePage的內存分配機制之後,測試時間有了一定程度的縮短,這就說明hugepage比傳統X86的內存頁大得多而使得測試過程中節省了大量的內存頁分配時間。

但是,設置Hugepage之後這部分的內存會直接被其佔用管理,也就是說操作系統無法再對這部分內存做任何操作,所以在設置Hugepage的時候我們需要合理地做好規劃,儘量提升Hugepage帶來的優點。


4. 磁盤部分

相對於CPU和內存的發展步伐,硬盤技術的發展確實是不給力。所以在現今的企業IT架構中,往往磁盤I/O纔是真正的瓶頸。對於虛擬化來說,磁盤性能也直接影響着虛擬機的性能。

下面我們將針對兩種最常見的虛擬機磁盤鏡像格式:Qcow2Raw,一個是COWCopyon Write)設備,一個是RAW設備。根據我們以往的瞭解,我們知道qcow2格式的鏡像佔用空間小,這也是所有COW設備的優點,而RAW設備則是完全的磁盤大小,但是據說讀寫性能優於Qcow2

下面就讓我們通過嚴謹的測試分析,找到最適合我們使用的鏡像格式,從而整體提升OpenStack的性能。

 

4.1 Qcow2Raw哪個最適合我們?

4.1.1 環境介紹

本次測試我們主要圍繞着從虛擬機中讀取和寫入數據時,不同磁盤文件的讀寫性能表現。我們將在同一臺宿主機上開啓兩臺完全相同規格的虛擬機,他們採用統一的鏡像,只是利用qemu-img轉換了鏡像的格式。

我們分別以100M500M1000M爲單位在不同格式的虛擬機上做讀取數據和寫入數據的操作,利用time統計操作的時間,以此來對比不同磁盤格式的虛擬機讀寫數據的性能。


4.1.2 測試分析

Qcow2磁盤格式的虛擬機中,我們利用dd工具從隨機數中寫入到某個文件中,通過time來統計完成時間。

以下是測試數據統計表:

wKiom1kW0QvBsPUGAAAxQmti6PM485.png

接下來,我們在RAW磁盤格式的虛擬機中執行相同的測試,利用time統計完成時間,數值越小表示性能越好,數據如下:

wKioL1kW0RWjK2j5AAAwmsupHUM213.png

根據以上兩種磁盤格式的測試結果,我們可以將數據彙總起來,並形成更加直觀的圖表:

wKioL1kW0R-Td_jrAAAwnnv28R8026.png

wKiom1kW0T_gOiopAABINBmz_1s920.png

將兩種磁盤格式的讀性能數據彙總起來,形成圖表如上。

可以看到RAW格式的讀性能是完全優於Qcow2格式的,所以如果我們的鏡像存儲不再需要考慮鏡像佔用空間大小的話,RAW格式可以提供更加優秀的讀性能。

wKioL1kW0ayif7FAAAAzC5KkTrE695.png

wKiom1kW0azzVnXSAABDTUXcadI546.png

將兩種磁盤格式的寫性能數據彙總起來,形成圖表如上。

相對於讀性能的差距,寫性能的對比相對沒有這麼明顯,但是在寫性能方面,依然是RAW格式具有更好的性能。


4.1.3 優化實踐

根據以上的讀寫測試與分析,我們可以知道RAW設備是優於Qcow2設備的,但是我們考慮技術的選型不應該僅僅從性能出發,例如當我們需要考慮到鏡像存儲的容量問題時、當我們需要考慮虛擬機啓動加載問題時,在Openstack中運算節點啓動虛擬機需要先從鏡像池中拷貝一份備份,之後再從運算節點上啓動,這樣Qcow2格式的特點顯然能使啓動速度提升一個檔次。

具體的選型需要全面的分析和規劃。


5. 網絡部分

對於所有的虛擬化來說,其所獲得的資源都是來自硬件的,只是利用資源利用的機制,提高了資源利用率。同樣地,虛擬化的網絡性能與宿主機的網卡性能和吞吐率也是直接關聯的,所以在網絡方面我們可以調整的並不多。

下面我們將針對KVM中的virtIO驅動器進行測試,KVM默認的I/O驅動爲IDE,而virtIO驅動由於其機制上的創新而具有更高的性能,那麼virtIO究竟能爲我們提升多少性能呢?


5.1 VirtIO究竟有多大能耐?

首先,大家一定很想知道什麼是virtIO

虛擬化的方方面面都在高速發展,唯有I/O部分始終難以突破。如何讓Hypervisor能夠在I/O虛擬化方面充分地利用底層內核呢?答案是使用virtio驅動,它爲hypervisor提供一組通用的 I/O 虛擬化驅動程序,提供高效的抽象。

wKioL1kW0dPTdSzTAAD5Gm21FLw495.png

如上圖,VirtIO其實是一個基於半虛擬化的產品,在KVM的應用中,virtIO會在Qemu空間內爲虛擬機提供一個I/O虛擬的前端,而在Hypervisor上提供一個後端和設備虛擬的功能,這樣虛擬機與宿主機之間的I/O通信就不再是通過Hypervisor的物理信號模擬(效率低),而是通過virtIO的機制進行通信,大大提高了I/O效率。


5.1.1 環境介紹

本次測試我們將分爲虛擬機與物理機之間的數據傳輸、虛擬機與虛擬機之間的數據傳輸。當然,本次測試環境中虛擬機與物理機都是處於同一個局域網的,保證測試環境的一致性。


5.1.2 測試分析

下面,我們首先在不開啓virtIO的情況下做數據傳輸測試,我們利用dd命令創建了一個1G大小的文件,我們將使用scp命令進行傳輸,利用time工具計算整個傳輸過程所使用的時間,之後計算出本次傳輸的平均傳輸速率。

以下是未使用VirtIO驅動的測試數據:

wKioL1kW0ruzJ62pAAAqUz6U2TM990.png

以下是使用了VirtIO驅動的測試數據:

wKiom1kW0sfBZdZOAAAonl0GXIE646.png

wKioL1kW0seBGrObAAA9Ni80z6U043.png

我們將上面兩組數據進行彙總,得到如上數據對比表。通過傳輸的速率我們可以看到,使用了VirtIO之後的傳輸速率得到了驚人的提升,下面我們將數據形成圖表,如下。

wKioL1kW0uuSw6q7AABBRIzgW3k355.png

根據以上的圖表,我們看到開啓VirtIO之後,無論是虛擬機與虛擬機、物理機與虛擬機之間的數據傳輸速率相差不多,這也是VirtIO的主要特點之一。在我們本次測試中,傳輸速率大概在27MB/s,這樣速度在千兆網卡的環境下已經是超凡的表現了。


5.1.3 優化實踐

根據以上的測試和分析,我們知道使用VirtIO驅動是有百利無一害的,因爲VirtIO的機制使得KVM這類完全虛擬化產品最大的弊端以及企業級應用中最大的瓶頸得到解決。

所以在OpenStack系統中,我們需要在nova.conf主配置文件中加入VirtIO的相關參數“libvirt_use_virtio_for_bridges=True”,這樣將爲各節點之間連接的網橋啓用VirtIO,極大提升I/O性能。


6. 總結

至此,本次KVM虛擬化性能測試與優化實踐完結了。通過本次CPU、內存、磁盤、網絡4方面的測試分析,我們更加深入地瞭解了KVM的性能,同時也找到了一些適合生產環境使用的強悍的技術。

性能優化的工作並不是做簡單的性能測試,更重要的是在實際的生產環境中,在真實的線上壓力下,全面測試性能和穩定性,根據我們業務的需求找到最適合我們的技術,這纔是性能優化的根本宗旨。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章