1. 程式人生 > >2017版:KVM效能優化之CPU優化

2017版:KVM效能優化之CPU優化

前言

任何平臺根據場景的不同,都有相應的優化。不一樣的硬體環境、網路環境,同樣的一個平臺,它跑出的效果也肯定不一樣。就好比一輛法拉利,在高速公路里跑跟鄉村街道跑,速度和激情肯定不同…

所以,我們做運維工作,也是如此。首先你得充分了解你所用的軟體平臺,然後根據你現有的生產環境去充分的測試,最後得出結果,做最優的調整。

KVM也是一樣,首先要做的是充分的瞭解它,看看有哪些引數和設定我們可以做出調整,最終應用以求發揮最高的效能。

那麼KVM的效能調優,我們可以從四個方面入手 —— CPU、記憶體、磁碟IO、網路。

KVM CPU效能調優

CPU這塊我們是針對NUMA這塊的調優,那麼什麼是NUMA呢?NUMA是英文 Non Uniform Memory Access Architecture 的縮寫,意思就是非統一記憶體訪問,它是一種解決多CPU共同工作的解決方案。我們知道現在的伺服器配置都比較高了,CPU很多都是多路多核的,而且CPU是需要跟儲存器進行資料互動的,以往的年代,那時候的CPU運算速率不高,而且都是單CPU模式,那麼儲存器裡的資料要放到CPU裡進行運算這是完完全全跟得上的。但是現在的CPU運算速度大大增強了,而且都是多CPU模式,於是就出現了不平衡,那就是儲存器裡的資料完全不夠讓CPU消化,並且還會出現多個CPU搶食儲存器的情況… 這種情況下CPU就表現得非常的飢渴… 資料不夠享用,而且儲存器還不夠分配。

因此電腦科學家為了提升計算機的效能,就認真的研究了下CPU和儲存器之間的協調互動模式。總體核心思想就是尋找一個多CPU模式下,如何讓CPU能最大化的“享用”更多來自多個儲存器的資料。

於是就設計出了以下幾套解決方案:

1.1 SMP技術

最開始是SMP技術,SMP(Symmetric Multi-Processing )技術就是對稱多處理結構,這種結構的最大特點就是CPU共享所有資源,比如匯流排,記憶體,IO系統等等。

既然是共享所有的資源,所以,各個CPU之間是平等的關係,然後作業系統管理著這些CPU對資源的訪問(通常是用佇列的形式去管理)。每個CPU依次的去處理佇列中的程序,如果兩個CPU同時訪問,那麼一般是通過軟體鎖的機制去解決爭奪的問題,軟體鎖這概念跟開發裡的執行緒安全鎖機制道理是一樣的,當一個CPU處理著一程序,一般會先鎖住,處理完再釋放。

所以說到這裡,這裡的對稱指的就是CPU之間是平等的無主從,訪問資源也是平等的。我們可以看下面這張圖:

CPU

這個結構是最早出現的方案,但是就是因為最早出現,所以它的弊端很快就顯現出來了,那就是它的擴充套件能力不強。我們看上面這張圖就明顯感覺到,如果伺服器要提升效能增加CPU,那麼記憶體(記憶體最大化的情況下)就明顯不夠了,因為是共享模式,多一個CPU就多一個吃記憶體資料的人…  因此多增加的CPU沒法享受到記憶體的資料,就會停歇,這樣就造成了CPU的浪費。

有實驗資料表明,SMP型的伺服器CPU最好是2-4顆就OK了,多餘的就浪費了。

SMP

由此可見,這種方式是有缺陷的。。。因此科學家又想到了另外一個結構方案,那就是NUMA。

1.2 NUMA技術

NUMA剛才我們在前面說了是非統一記憶體訪問的意思,它的出現就很好的解決了SMP的擴充套件問題。有了NUMA技術那麼就可以把幾十個甚至上百個CPU組合在一個伺服器內。

NUMA架構設計圖:

NUMA技術

從圖中我們發現,每個CPU模組之間都是通過互聯模組進行連線和資訊互動,CPU都是互通互聯的,同時,每個CPU模組平均劃分為若干個Chip(不多於4個),每個Chip都有自己的記憶體控制器及記憶體插槽。

在NUMA中還有三個節點的概念:

  1. 本地節點: 對於某個節點中的所有CPU,此節點稱為本地節點。
  2. 鄰居節點:與本地節點相鄰的節點稱為鄰居節點。
  3. 遠端節點:非本地節點或鄰居節點的節點,稱為遠端節點。

鄰居節點和遠端節點,都稱作非本地節點(Off Node)。

這裡要注意的是,CPU訪問不同型別節點記憶體的速度是不相同的,訪問本地節點的速度最快,訪問遠端節點的速度最慢,即訪問速度與節點的距離有關,距離越遠訪問速度越慢,此距離稱作Node Distance。正是因為有這個特點,所以我們的應用程式要儘量的減少不通CPU模組之間的互動,也就是說,如果你的應用程式能有方法固定在一個CPU模組裡,那麼你的應用的效能將會有很大的提升。

CPU

訪問速度:本地節點>鄰居節點>遠端節點

因此KVM也是一樣,我們在CPU優化這塊就是要讓KVM繫結在指定的CPU上,這樣減少跨CPU的互動使用,讓KVM的效能提升。現在我們的伺服器還有linux作業系統都是預設走NUMA模式,所以我們接下來說說如何去做CPU的繫結。

那麼具體如何操作?

1.3 numactl 命令講解

我們這裡用一臺真實的物理機演示,這臺物理機的是IBM 3650M4。

首先我們用numactl命令檢視NUMA的情況,如果你係統沒有這個命令,用 yum install numactl 安裝下即可。

 命令講解

OK,以上是numactl的詳細命令,那麼接下來我們先看看當前伺服器CPU的numa情況:

我們執行lscpu命令可以檢視到一些CPU資訊:

scpu

我們用numactl –hardware可以檢視,如這裡我準備了兩臺IBM的伺服器,一個3650M4另外一個是3850M2。

我們可以從命令返回的情況看出,這臺伺服器numa有2個node(node0和node1):

numa

我們再看另外一個伺服器,這是一臺IBM 3850M2,那麼它就只有一個node:

node

通過這個numactl –hardware命令,我們可以看出上面那臺機器每個node有81894 MB的記憶體可以使用(大概79G),而IBM 3850M2這個伺服器node有131070MB(120多G)記憶體可用(基本上是整個伺服器的記憶體)

那麼接下來我們可以看下cpu numa的排程分配情況:

我們執行numastat命令可以查到:

numasta

3650M4

3850M2

引數解釋:

  • numa_hit 使用本節點記憶體次數
  • num_miss  計劃使用本節點記憶體而被排程到其他節點次數
  • num_foregin  計劃使用其他節點記憶體而使用本地記憶體次數
  • interleave_hit  交叉分配使用的記憶體中使用本節點的記憶體次數
  • local_node  在本節點執行的程式使用本節點記憶體次數
  • NB other_node  在其他節點執行的程式使用本節點記憶體次數

接著我們看下這個命令:numastat -c  , 這個命令c 後面跟上程序名就能看到相關程序的NUMA記憶體使用情況。比如:numastat -c qemu-kvm,這樣我們就知道了qemu-kvm這個程序,它在node0 和node1上使用的記憶體大小,單位是MB:

OK 通過這幾個命令我們可以檢視一些numa的基本狀態和使用情況。那麼針對CPU Numa技術,linux作業系統本身呢也有自身對這塊的設計。拿linux來說,它預設使用的就是NUMA自動平衡策略,也就是說,系統會自動的調配numa的記憶體使用,以求一個平衡。

當然,這個設定是可以使用者自己控制的,如果我們想關閉,直接執行

# echo 0 > /proc/sys/kernel/numa_balancing    即可

# echo 1 > /proc/sys/kernel/numa_balancing    就是開啟

1.4 CPU繫結操作

說到這,既然我們的作業系統還有CPU特性都採用了NUMA架構,那麼我們完全可以通過調整KVM對應的NUMA關係來達到KVM CPU這方面的優化。這裡,我們一般是通過CPU繫結的方法來做相關操作的。

那麼具體的操作是怎麼樣的呢?那麼接下來我們通過一個例子來演示。這裡是一臺物理機,之前我們看過了,現在上面裝好了KVM,然後執行著幾個虛擬機器,我們用 virsh list 命令可以檢視到當前執行的虛擬機器列表。

繫結操作

比如我們要看這個Win7-ent虛擬機器裡vCPU對應物理CPU的情況,那麼可以執行: # virsh vcpuinfo Win7-ent  可以檢視

繫結操作

這個虛擬機器是2個vCPU 雙核的,然後都是跑在了物理機的CPU8上,使用的時間是2964.6s。最後一個是CPU的親和性,這個yyyyy 表示的是使用的物理CPU內部的邏輯核,一個y就代表其中一個CPU邏輯核。全部是y ,那麼說明這臺物理機的24個CPU核,這個CPU都能排程使用。

當然,我們可以進入vrish ,然後執行emulatorpin Win7-ent, 通過這個命令我們可以更詳細的得到這個虛擬機器可以用哪幾個核:

我們可以看到目前這個虛擬機器0-23的CPU它都能排程使用

那麼以上就是檢視虛擬機器CPU NUMA排程的資訊,如果我們要把虛擬機器繫結到固定的CPU上,我們就要做以下操作: # virsh emulatorpin Win7-ent 18-23 –live   通過這個命令,我們把這個win7的虛擬機器vCPU繫結在了18-23這6個CPU之間的核上。

我們用命令檢視下 emulatorpin Win7-ent

我們也可以用virsh dumpxml Win7-ent 檢視確認:

這是讓虛擬機器裡的vCPU一起繫結的方法。

那麼有的人會疑問,一個虛擬機器我有兩個vCPU, 比如這個win7 ,它就是雙核的,我想讓裡面的vCPU1和vCPU2分別繫結在不同的物理CPU上可以嗎?怎麼操作呢?這也是可以的,我們通過下面的方法可以進行相關的vCPU分別繫結

# virsh vcpupin Win7-ent 0 22

# virsh vcpupin Win7-ent 1 23

# virsh dumpxml Win7-ent

# virsh vcpuinfo Win7-ent

OK,這裡要注意的是,你把虛擬機器用reboot重啟,這個繫結配置還是生效的,但是你shutdown的話,CPU繫結的效果會失效。我們要讓VM關機然後起來也生效,就必須把引數寫入到虛擬機器的XML裡,然後儲存,這樣關機了也不會失效,這裡要注意下

OK,以上就是CPU繫結技術的操作。通過這樣的操作,我們可以在一臺多CPU的物理機上固定幾個CPU給虛擬機器用。當然,至於為什麼可以這樣做,前面我們提到了關於NUMA的原理,如果固定了虛擬機器的CPU,那麼它就不會去找遠端節點了,另外就是有些場景下,一物理機多個CPU,如果前面幾個CPU負載很高,利用率大,後面幾個CPU利用率低,那麼我們可以協調下,做CPU的繫結,平衡下CPU的負載。

以上是CPU的繫結,接下來我們講講CPU的熱新增。

1.5 CPU 熱新增

首先我們先了解下什麼叫熱新增,熱新增就是在虛擬機器執行不關機的情況下,做CPU的新增操作。那麼要注意的是,這個熱新增是在Redhat7.0以後才出現的,之前是沒有的。所以要享用這功能那必須要求KVM宿主機和虛擬機器都得在7.0版本以後。那麼具體怎麼操作我們通過一個演示給大家操作下。

比如目前這個虛擬機器,這是一個CentOS7.1的。我們先看下目前虛擬機器的CPU的數值,我們可以進系統檢視,cat /proc/cpuinfo| grep “processor”| uniq| wc -l ,我們看到當前是2個CPU:

然後我們解釋下這個最大CPU分配數是怎麼個意思,它的意思就是給這個虛擬機器最大預留的CPU個數,這個設定很重要,如果你想給虛擬機器熱新增,那麼這個設定必須寫。比如我們這裡寫的4,那麼我們可以給虛擬機器最大熱新增到4個CPU,而且4是上限。

那麼接下來說下,具體怎麼熱新增。我們先在宿主機裡先給這個虛擬機器新增第三個CPU,原來是2個,現在再新增一個變成3個: setvcpus VM3_CentOS7.1 3 –live

然後我們到虛擬機器裡面把這個CPU啟用 :

echo 1 >/sys/devices/system/cpu/cpu2/online

我們再執行檢視,發現已經變成3個了。

如果要減少,那麼只能在虛擬機器裡減少剛才的CPU

# echo 0 >/sys/devices/system/cpu/cpu2/online

但是在宿主機層面看這個虛擬機器的vCPU數還是3個,也就是說不支援熱減少,我們執行vcpuinfo VM3_CentOS7.1命令發現還是3個:

同理,Windows的新增也是如此,直接在宿主機裡新增第三個CPU即可

# setvcpus VM4_Win2008 3 –live

然後虛擬機器裡不用操作,它會自動重新整理成3個CPU,我們也可以一個windows虛擬機器做相關的演示,具體的可以由讀者自己操作了。

到這為止, 以上就是KVM CPU方面的優化。總結起來就兩點,一個是CPU繫結,還有一個就是熱新增。

CPU繫結首先得了解NUMA技術,然後站在整個宿主機CPU資源的層面去調節。

熱新增,當你某個虛擬機器正在執行,然後突然業務壓力增大了,可以通過這方法達到0停機提升虛擬機器CPU效能。

參考連結:

文章來自微信公眾號:雲技術實踐