
前言
持續提升虛擬機性能是所有云計算工程師研究的方向,其中一個重要方式便是使用大頁內存。本文從內存映射出發為讀者淺析大頁內存的相關概念和基礎操作,并以此為延伸,與各位分享華云產品技術中心計算團隊在大頁內存動態分配方面的探索與實踐。
MMU 與內存映射
在計算機系統結構中,我們知道,CPU是通過尋址來訪問內存的。例如,32 位 CPU 的尋址寬度是 0~0xFFFFFFFF ,通過換算可得為 4G,即可支持的物理內存最大是 4G。
然而在實踐過程中會產生各種各樣的問題,若某個程序需要使用 4G 內存,而此時可用的物理內存小于 4G,這就導致程序不得不降低內存的占用。因此為了解決此類問題,現代 CPU 引入了 MMU(Memory Management Unit 內存管理單元)。MMU 的核心思想是利用虛擬地址替代物理地址,即CPU尋址時使用虛址,由 MMU 負責將虛址映射為物理地址。 MMU的引入,解決了對物理內存的限制。
而內存映射則是將虛擬內存地址映射到物理內存地址。為了完成內存映射,內核為每個進程都維護了一張頁表,記錄虛擬地址與物理地址的映射關系。
頁表實際上存儲在 CPU 的內存管理單元 MMU 中,這樣,CPU 就可以直接通過硬件,找出要訪問的內存。

什么是 HugePages
大頁內存(HugePages),顧名思義就是擁有更大頁面的內存頁,HugePages 提供了 4K 頁面大小的替代方案,即提供更大的頁面,在特定場景下對于性能有著非常明顯的提升。
HugePages 的查看與分配
在 Linux 中,可以使用如下命令查看大頁內存

我們對其中的字段分別做一下解釋
AnonHugePages: 透明大頁的大小HugePages_Total: 大頁資源池中的大頁總量HugePages_Free: 池中未使用的大頁的數量HugePages_Rsvd: 已經被分配預留但是還沒有使用的大頁數目HugePages_Surp: 池中大于/proc/sys/vm/nr_hugepages 中值的 HugePages 數量HugePagesize: 單塊大頁的大小
通常來說,我們會使用 2M 的大頁,即 HugePagesize = 2048 KB。
請注意,這里關于大頁所有的單位都是數量(頁),而不是大小(KB)。舉個例子,如圖所示,HugePages_Total 的值為 100,那么在這臺機器上大頁會占用多少的內存呢?
答案是 200M,即 HugePages_Total * HugePagesize,100 * 2048KB = 200M。
那么,如何分配 HugePages 呢?
分配 HugePages 主要有兩種方法。
一是修改 /etc/grub2.cfg 文件中啟動菜單的內核參數,這樣做的好處在于,當系統啟動時,擁有連續內存的空間(用于 HugePages 分配)的機會要大得多。
二是通過 sysctl vm.nr_hugepages 的命令進行臨時分配,這種方式勝在分配靈活,而弊端則是,當系統內存被使用到一定程度時,連續內存頁的數量會變少,即在物理內存有剩余時,卻無法分配 HugePages 。
OpenStack 社區的方案
在 OpenStack 中,libvirt 的 driver 會去檢查用戶是否在 flavor 中配置大頁的相關選項,并直接從已分配的資源池中劃分相關資源給虛擬機。
這就帶來了一個問題,即大頁資源池需要用戶提前分配。提前分配好的大頁資源池會直接占據這部分的內存空間,且隨著資源池內可用大頁數量的降低,用戶在一段時間后無法繼續創建大頁內存的虛擬機。
歸根結底,OpenStack 本身并沒有提供一套用于管理和維護大頁資源池的機制。
ArStack 做了哪些嘗試
這就回到了這篇分享的主題,有什么辦法能夠盡可能多地創建高性能的大頁虛擬機,同時又避免云平臺初期大頁資源池分配時,過多地占用系統內存呢?
基于這一出發點,華云計算團隊設計了一套動態維護大頁資源池的系統。
用戶可以在系統初始化時,以一個較低的值手動設置初始大頁資源池的大小,Nova 的某個周期性定時任務會在一定時間間隔內檢查各個計算節點的大頁資源池是否滿足預設的策略。
當初始資源池消耗殆盡時,Nova 會對大頁資源池進行自動擴容,以維持一個資源相對富裕的狀態。同時,Nova-Scheduler 在創建大頁虛擬機時也會對各個節點的計算資源進行檢查,若都不滿足虛擬機所需資源, Nova-Scheduler 會計算相應的資源缺口,并嘗試進行擴容。
在大頁虛擬機被刪除后,相應的大頁資源會被釋放,并流入大頁資源池。此時,Nova 檢測到該計算節點的大頁資源池存在過多未被分配的大頁時,會進行縮容操作,以釋放被占用的物理內存,從而減少了物理內存占用過多的情況。
基于這套動態分配方案,最終實現了性能與靈活兼得的目標。
后記
OpenStack 中很多邏輯都是牽一發而動全身的,在實踐過程中,Nova-Scheduler 、NUMA 以及 ArStack 的內存預分配都針對 HugePages 相關場景進行了對應的調整和優化。
在此感謝計算團隊所有同學的辛勤付出。未來,ArStack 會繼續努力,持續為用戶提供更加優質的私有云產品。






