KVM性能優化之內存優化

轉自https://blog.csdn.net/dylloveyou/article/details/71338378


我們說完CPU方面的優化(http://blog.csdn.net/dylloveyou/article/details/71169463),接着繼續第二塊內容,也就是內存方面的優化。內存方面有以下四個方向去着手:

  1. EPT 技術
  2. 大頁和透明大頁
  3. KSM 技術
  4. 內存限制

EPT技術

EPT也就是擴展頁表,這是intel開創的硬件輔助內存虛擬化技術。我們知道內存的使用,是一個邏輯地址跟物理地址轉換的過程。虛擬機內部有邏輯地址轉成成物理地址的過程,然後再跳出來,虛擬機這塊內存又跟宿主機存在邏輯到物理的轉換。有了EPT技術,那麼能夠將虛擬機的物理地址直接翻譯爲宿主機的物理地址,從而把後面那個轉換過程去掉了,增加了效率。

那麼這項技術,現在的服務器都支持,只要在BIOS打開了intel 的VT設置,這個也一起打開了。

所以這個基於硬件的優化,目前不需要做額外的什麼操作。 
這裏寫圖片描述

大頁和透明大頁

我們先解釋什麼叫大頁。

所謂的大頁指的是內存的大頁面。當然,有大頁面必然有對應的小頁面… 我們知道內存採用的是分頁機制,當初這個機制提出的時候,計算機的內存大小也就幾十M,所以當時內存默認的頁面大小都是4KB,那麼這個4KB 也就是所謂的小頁面。但是隨着計算機的硬件發展,現在的內存基本上都是幾十G 甚至上百G了,雖然,如果還是4KB小頁的方式,那麼必然會存在一些問題。那麼會有哪些問題呢?操作系統如果還是小頁存在,那麼將會產生較多的TLB Miss和缺頁中斷,從而大大影響性能。

爲什麼小頁就存在較多的Miss和缺頁中斷呢?比如說系統裏的一個應用程序需要2MB的內容,如果操作系統還是以4KB小頁爲單位,那麼內存裏就要有512個頁面(512*4KB=2M),所以在TLB裏就需要512個表項以及512個頁表項,因此操作系統就要經歷512次的TLB miss和512次的缺頁中斷才能將2MB的應用程序空間全部映射到物理內存裏。想想,2MB內存的需要就要經歷512次的操作,如果內存需求大呢?必然操作數量會大大增加,從而間接的影響性能。

如果把這個4KB變成2MB呢?那就很輕鬆了,一次TLB Miss和缺頁中斷操作就完成了,大大的增加了效率。

所以,虛擬機可以通過分配巨型頁也就是剛纔說的大頁來提高運行性能。

那麼具體怎麼操作呢?也就是說如何把這個4KB的小頁變成2MB甚至1GB的大頁,然後把這個大頁賦給虛擬機使用?

我們可以先通過命令 cat /proc/meminfo | grep HugePages查看當前系統有多少個大頁: 
這裏寫圖片描述 
我們看到,當前數量是0。

那麼如何設置大頁的數量呢?也就是上面的HugePages_Total的數量。

只要運行echo 2000 > /proc/sys/vm/nr_hugepages 這個命令即可: 
這裏寫圖片描述 
已經變成了2000了。

當然這樣重啓會失效,我們運行這個命令讓它永久生效 :

sysctl -w vm.nr_hugepages=2000
  • 1

運行了這個命令系統重啓的話,大頁的數量也將是保持2000,不會變。 
接下來,我們還得把大頁進行掛載,我們運行:

# mount -t hugetlbfs hugetlbfs /dev/hugepages 
  • 1

這個hugetlbfs 是一種特殊文件系統,那至於爲什麼採用這樣的文件系統是因爲這樣花費的代價小。

通過這幾步操作,開啓->設置大頁數量->掛載, 那麼宿主機這塊就沒什麼問題了。

如果我們KVM裏面的某個虛擬機要使用宿主機的大頁,那麼我們還得做如下操作:

  1. 重啓下libvirtd服務
  2. 虛擬機也開啓透明巨型頁
  3. 關閉虛擬機編輯虛擬機XML設置虛擬機可以使用宿主機的巨型頁數量

我們先看看,當前的大頁是沒進程用的, hugepages_free是2000: 
這裏寫圖片描述

我們先把libvirtd服務重啓:systemctl restart libvirtd.service

然後,我們看看虛擬機的透明大頁有沒有打開,一般默認系統是打開的,我們確認下 
這裏寫圖片描述 
我們看到是always狀態,那麼就是打開的,OK,我們進行下一步。

編輯虛擬機XML文件,讓它使用宿主機的大頁。

我們先把虛擬機關閉,然後 virsh edit vmname 命令修改,添加下圖中紅色框框的內容: 
這裏寫圖片描述

修改後,保存,然後開啓虛擬機,注意這個虛擬機的內存是2G的配置。

最後我們在宿主機運行cat /proc/meminfo | grep -i HugePages 查看下大頁的使用情況 
這裏寫圖片描述

我們發現hugepages_free 已經變成了912個了,那麼使用了2000-912=1088 個。

Hugepagesize是2M,也就是每頁頁面的大小,使用了1088個頁面,那麼2*1088=2176M 正好跟虛擬機內存的大小2G差不多。

如果想讓虛擬機釋放大頁,那麼只要把這個虛擬機關機或者刪除XML裏剛纔添加的配置。

剛纔的操作,我們只是針對一個虛擬機的,也就是說我們把大頁面賦給了一個虛擬機。如果我們要賦予多個虛擬機怎麼辦?

那麼要讓大頁同時讓多個虛擬機享用,有以下兩步要做:

  1. 給NUMA 各個node節點分配多個2MB或者1GB的大頁
  2. 編輯虛擬機xml文件以使用node裏分配好的大頁

我們可以運行下面兩個命令就可以給宿主機各個NUMA Node分配大頁

# echo 4 > /sys/devices/system/node/node0/hugepages/hugepages-1048576kB/nr_hugepages
# echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
  • 1
  • 2

這兩個命令的意思就是先給node0裏分配4個1GB的大頁,然後再給node1分配1024個2MB的大頁。

然後執行相關掛載操作,這跟剛纔我們做的操作類似:

# mkdir /dev/hugepages1G
# mount -t hugetlbfs -o pagesize=1G none /dev/hugepages1G
# mkdir /dev/hugepages2M
# mount -t hugetlbfs -o pagesize=2M none /dev/hugepages2M
  • 1
  • 2
  • 3
  • 4

掛載成功後,重啓下libvirtd服務,然後虛擬機就可以使用了,但是這裏要注意的是,1GB的大頁,虛擬機是不能直接使用的,需要在XML裏指定。

那麼怎麼指定? 我們目前宿主機NUMA node1和node2裏面分別有4個1GB的和1024個2MB的大頁。因此,只要跑在這兩node上的虛擬機都可以享用了。

比如剛纔我們那虛擬機,我們要讓它使用1GB的大頁,我們只需要在XML裏這樣定義:

<memoryBacking>      
  <hugepages/>          
    <page size="1" unit="G" nodeset="0-3,5"/>          
    <page size="2" unit="M" nodeset="4"/>      
  </hugepages> 
</memoryBacking>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

紅色的部分就是要添加的參數,size是1,表示第一個使用的page;然後單位unit是G,nodeset=”0-3,5” 意思是虛擬機的NUMA node0,node1, node2 , node3和node5將使用1GB的大頁 ; 虛擬機的node4將用2MB的大頁。

注意,這裏的nodeset指的是虛擬機的節點,同時還要注意的是,如果宿主機大頁面不夠用了,你這樣配置了,虛擬機是會起不來的。

以上就是給虛擬機分配大頁的方法。當然如果你想把宿主機的大頁關閉,只要執行:

# sysctl vm.nr_hugepages=0
# umount hugetlbfs
  • 1
  • 2

接下來我們講下透明大頁。

從Centos6開始,linux系統自帶了一技術叫透明巨型頁(transparent huge page),它允許所有的空餘內存被用作緩存以提高性能,而且這個設置是默認開啓的,我們不需要手動去操作。

Centos下,我們用cat /sys/kernel/mm/transparent_hugepage/enabled可以查看 
這裏寫圖片描述

我們看到這個中括號把這個always括起來了,說明這機器的透明巨型頁的功能是打開的。當有512個頁面可以整合的時候,就會合成一個2MB的大頁;如果是在括號把never括起來了,那麼就是關閉狀態;madvise的話就是避免改變內存佔用。

當然,如果你想改變透明巨型頁的狀態,比如說關閉它,那麼運行下面的命令即可:

# echo never >/sys/kernel/mm/transparent_hugepage/enabled
  • 1

這裏寫圖片描述

最後要注意的是透明巨型頁跟剛纔我們說的hugetlbfs 文件掛載大頁是不衝突的,如果你沒做任何大頁的指定和掛載,那麼KVM就會使用透明大頁的方式。

那麼說到這,大家就會疑問,既然有透明大頁,我爲何還要費勁的去做相關大頁的指定? 其實這兩種方式都差不多,區別就是一個是手動的一,個是自動的。如果你對你宿主機資源把握的更加精準,推薦的還是手動指定。

KSM 技術

KSM是什麼呢?KSM(Kernel SamePage Merging),也就是所謂的相同頁面內存壓縮技術。

KSM服務在linux系統裏默認是開啓的,它的作用就是讓內存利用的更加高效,我們知道內存是分頁的,如果多個程序中用的內存都是相同的頁面,那麼KSM就會把相同的內存合併,這樣就能騰出更多的空間。

KSM在系統裏有個守護進程,它的作用就是不斷的掃描宿主機的內存情況,檢測有相同的頁面就會合並,這或多或少會消耗CPU。

下面有幾個命令設置大家要了解: 
首先是開關KSM服務:

systemctl start|stop ksmd
systemctl start|stop ksmtuned 
systemctl enable|disable ksmd
systemctl enable|disable ksmtuned
  • 1
  • 2
  • 3
  • 4

如果你的環境,內存資源比較豐富,VM又不多,這個功能開不開啓都無所謂;如果不夠,又想跑多一點的虛擬機,那麼可以打開這個功能。但是你一定要注意,這個是一種內存超用的方案,如果一臺宿主機裏大部分虛擬機內存變化比較頻繁,那麼要慎重開啓,因爲KSM會頻繁的做內存掃描,不停的做內存合併操作,這會大量的消耗CPU資源,如果內存不夠還會用到swap,那麼最終會嚴重影響虛擬機性能。

當然,也有設置能讓虛擬機不受宿主機KSM的影響,具體操作如下:

編輯虛擬機的XML文件,添加:

<memoryBacking>
    <nosharepages/>
</memoryBacking>
  • 1
  • 2
  • 3

這樣,這個KSM就不會去合併這個虛擬機的內存了。

總的來說,如果你的環境硬件配置比較高,同時又追求VM數量,把KSM打開是一個很不錯的選擇(但是一定要做好相關資源的實時監控,特別是CPU)。在筆者維護過的項目中,遇到過只追求數量而不追求性能的場景,當時我們就開啓了KSM服務,服務器配置是雙路E5-2690 [email protected] 48core、512G內存,當每臺計算節點到80個VM的時候(VM大部分配置爲4c8G,windows和linux各佔50%)。用htop命令監控查看CPU每個核基本上都是99%滿負載,此時,虛擬機體驗十分不好,後來降到60個左右,CPU負荷在60%-70%,這樣情況纔有明顯好轉。

所以,用不用KSM視你自己的生產環境和客戶需求具體而定,這配置還是得慎重。

內存限制技術

通過虛擬機內存限制,可以讓虛擬機的內存使用限制在一定範圍內。

那麼這個操作有什麼作用呢?比如你的一臺KVM宿主機,裏面跑着多個業務的虛擬機,有的虛擬機業務比較大,喫得內存多,有的業務比較低,用不了多少內存,那麼我們可以通過內存限制技術來手動調節宿主機的內存分配。

當然這裏要說明的是,使用這個必須對你虛擬化環境特別清楚,比如宿主機平時的負載情況以及各個虛擬機的負載情況。

那麼具體如何操作呢?我們通過memtune命令或者通過改虛擬機的XML文件來設定內存的限制。

這個memtune命令有以下4個參數 
這裏寫圖片描述 
hard_limit:強制設置虛擬機最大使用內存,單位爲KB 
soft_limit:可用最大內存,單位爲KB 
swap_hard_limit:虛擬機最多使用的內存加上swap的大小,單位爲KB 
min_guarantee:強制設置虛擬機最低使用的內存,單位爲KB

最後一個參數雖然OPTIONS裏有列出,但是實測是發現CentOS7.0 以上系統不能支持,執行的時候會報下面這樣的錯誤: 
這裏寫圖片描述

centos6 雖然不會報這個錯,但是這命令貌似也不會有實際效果 
官方解釋這是一個bug,大家可以參考下面的鏈接: 
https://bugzilla.redhat.com/show_bug.cgi?id=1122455

–config : 寫入配置文件中,虛擬機重啓後生效 
–live :讓設置立即生效,但是虛擬機重啓後,效果消失 (如果不加–config –live –current 那麼默認是這個) 
–current :影響關機或者運行狀態的虛擬機,如果當前虛擬機正在運行,那麼虛擬機停止後,效果會消失

例:

# memtune VM3_CentOS7.1  --hard-limit 9437184 --config
  • 1

給虛擬機VM3_CentOS7.1 設置最大使用內存爲9G

# memtune VM3_CentOS7.1  --soft-limit 8388608 --config
  • 1

給虛擬機VM3_CentOS7.1 設置最大可用內存爲8G

# memtune VM3_CentOS7.1 --swap-hard-limit 10485760 --config
  • 1

限制虛擬機VM3_CentOS7.1最大內加可以使用的宿主機swap不超過10GB內存,注意設置這個值的時候必須大於hard-limit的所設置的值。

這個設置可以慎用,因爲虛擬機使用了swap那麼速度性能肯定會下降很多,而且要注意的是,這裏設置的內存大小必須大於hard-limit

# memtune VM3_CentOS7.1  --min-guarantee 4194304 --config
  • 1

這個命令我們可以操作下,但是演示會發現前面所說的error

以上是通過命令的方式,我們剛纔說了,還可以通過修改XML的方式來現在虛擬機的內存。

我們在XML裏添加下面這個配置即可:

<memtune>
      <hard_limit unit='KiB'>9437184</hard_limit>
      <soft_limit unit='KiB'>8388608</soft_limit>
      <swap_hard_limit unit='KiB'>10485760</swap_hard_limit>
</memtune>
  • 1
  • 2
  • 3
  • 4
  • 5

注意第四個參數min_guarantee加里面會報錯,虛擬機啓動不了。

以上幾點就是KVM在內存方面的相關調試設置。作爲工程師首先要做的是熟悉底層各種參數,然後根據生產環境和客戶需求做出最優配置,這樣才能得出最強的性能。

性能調優,這個很喫經驗,所以第一步還是熟悉下平臺裏原生有哪些設置參數以及它們的作用吧!

轉載自雲技術實踐微信公衆號,作者寶哥。


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