****1. 為什么需要 CPU 虛擬化****
X86 操作系統(tǒng)是設計在直接運行在裸硬件設備上的,因此它們自動認為它們完全占有計算機硬件吱肌。x86 架構提供四個特權級別給操作系統(tǒng)和應用程序來訪問硬件。 Ring 是指 CPU 的運行級別仰禽,Ring 0是最高級別氮墨,Ring1次之,Ring2更次之…… 就 Linux+x86 來說吐葵,
操作系統(tǒng)(內核)需要直接訪問硬件和內存规揪,因此它的代碼需要運行在最高運行級別
Ring0上,這樣它可以使用特權指令温峭,控制中斷猛铅、修改頁表、訪問設備等等凤藏。應用程序的代碼運行在最低運行級別上ring3上奸忽,不能做受控操作。如果要做揖庄,比如要訪問磁盤栗菜,寫文件,那就要通過執(zhí)行系統(tǒng)調用(函數)蹄梢,執(zhí)行系統(tǒng)調用的時候疙筹,CPU的運行級別會發(fā)生從ring3到ring0的切換,并跳轉到系統(tǒng)調用對應的內核代碼位置執(zhí)行,這樣內核就為你完成了設備訪問而咆,完成之后再從ring0返回ring3霍比。這個過程也稱作用戶態(tài)和內核態(tài)的切換。
那么暴备,虛擬化在這里就遇到了一個難題桂塞,因為宿主操作系統(tǒng)是工作在 ring0的,客戶操作系統(tǒng)就不能也在 ring0 了馍驯,但是它不知道這一點阁危,以前執(zhí)行什么指令,現在還是執(zhí)行什么指令汰瘫,但是沒有執(zhí)行權限是會出錯的狂打。所以這時候虛擬機管理程序(VMM)需要避免這件事情發(fā)生。虛機怎么通過 VMM實現 Guest CPU 對硬件的訪問混弥,根據其原理不同有三種實現技術:
全虛擬化
半虛擬化
硬件輔助的虛擬化
1.1 基于二進制翻譯的全虛擬化(Full Virtualization with Binary Translation)
客戶操作系統(tǒng)運行在 Ring 1趴乡,它在執(zhí)行特權指令時,會觸發(fā)異常(CPU的機制蝗拿,沒權限的指令會觸發(fā)異常)晾捏,然后 VMM 捕獲這個異常,在異常里面做翻譯哀托,模擬惦辛,最后返回到客戶操作系統(tǒng)內,客戶操作系統(tǒng)認為自己的特權指令工作正常仓手,繼續(xù)運行胖齐。但是這個性能損耗,就非常的大嗽冒,簡單的一條指令呀伙,執(zhí)行完,了事添坊,現在卻要通過復雜的異常處理過程剿另。
異常 “捕獲(trap)-翻譯(handle)-模擬(emulate)” 過程:
1.2. ****超虛擬化(或者半虛擬化****/****操作系統(tǒng)輔助虛擬化****Paravirtualization****)
半虛擬化的思想就是,修改操作系統(tǒng)內核贬蛙,替換掉不能虛擬化的指令雨女,通過超級調用(hypercall)直接和底層的虛擬化層hypervisor來通訊,hypervisor 同時也提供了超級調用接口來滿足其他關鍵內核操作速客,比如內存管理戚篙、中斷和時間保持。
這種做法省去了全虛擬化中的捕獲和模擬溺职,大大提高了效率岔擂。所以像XEN這種半虛擬化技術位喂,客戶機操作系統(tǒng)都是有一個專門的定制內核版本,和x86乱灵、mips塑崖、arm這些內核版本等價。這樣以來痛倚,就不會有捕獲異常规婆、翻譯、模擬的過程了蝉稳,性能損耗非常低抒蚜。這就是XEN這種半虛擬化架構的優(yōu)勢。這也是為什么XEN只支持虛擬化Linux耘戚,無法虛擬化windows原因嗡髓,微軟不改代碼啊。
1.3. ****硬件輔助的全虛擬化
2005年后收津,CPU廠商Intel 和 AMD 開始支持虛擬化了饿这。 Intel 引入了 Intel-VT (Virtualization Technology)技術。這種 CPU撞秋,有 VMX root operation 和 VMX non-root operation兩種模式长捧,兩種模式都支持Ring 0 ~ Ring 3 共 4 個運行級別。這樣吻贿,VMM 可以運行在 VMX root operation模式下串结,客戶 OS 運行在VMX non-root operation模式下。
而且兩種操作模式可以互相轉換廓八。運行在 VMX root operation 模式下的 VMM 通過顯式調用 VMLAUNCH 或 VMRESUME 指令切換到 VMX non-root operation 模式奉芦,硬件自動加載 Guest OS 的上下文赵抢,于是 Guest OS 獲得運行剧蹂,這種轉換稱為 VM entry。Guest OS 運行過程中遇到需要 VMM 處理的事件烦却,例如外部中斷或缺頁異常宠叼,或者主動調用 VMCALL 指令調用 VMM 的服務的時候(與系統(tǒng)調用類似),硬件自動掛起 Guest OS其爵,切換到 VMX root operation 模式冒冬,恢復 VMM 的運行,這種轉換稱為 VM exit摩渺。VMX root operation 模式下軟件的行為與在沒有 VT-x 技術的處理器上的行為基本一致简烤;而VMX non-root operation 模式則有很大不同,最主要的區(qū)別是此時運行某些指令或遇到某些事件時摇幻,發(fā)生 VM exit横侦。
也就說挥萌,硬件這層就做了些區(qū)分,這樣全虛擬化下枉侧,那些靠“捕獲異常-翻譯-模擬”的實現就不需要了引瀑。而且CPU廠商,支持虛擬化的力度越來越大榨馁,靠硬件輔助的全虛擬化技術的性能逐漸逼近半虛擬化憨栽,再加上全虛擬化不需要修改客戶操作系統(tǒng)這一優(yōu)勢,全虛擬化技術應該是未來的發(fā)展趨勢翼虫。
2. KVM CPU 虛擬化
KVM 是基于CPU 輔助的全虛擬化方案屑柔,它需要CPU虛擬化特性的支持。
2.1. CPU ****物理特性
這個命令查看主機上的CPU 物理情況:
要支持 KVM珍剑, Intel CPU 的 vmx 或者 AMD CPU 的 svm 擴展必須生效了:
2.2 ****多**** CPU ****服務器架構:****SMP****锯蛀,****NMP****,****NUMA
從系統(tǒng)架構來看次慢,目前的商用服務器大體可以分為三類:
多處理器結構 (SMP :Symmetric Multi-Processor):所有的CPU共享全部資源旁涤,如總線,內存和I/O系統(tǒng)等迫像,操作系統(tǒng)或管理數據庫的復本只有一個劈愚,這種系統(tǒng)有一個最大的特點就是共享所有資源。多個CPU之間沒有區(qū)別闻妓,平等地訪問內存菌羽、外設、一個操作系統(tǒng)由缆。SMP 服務器的主要問題注祖,那就是它的擴展能力非常有限。實驗證明均唉, SMP 服務器 CPU 利用率最好的情況是 2 至 4 個 CPU
海量并行處理結構 (MPP : Massive Parallel Processing) :NUMA 服務器的基本特征是具有多個 CPU 模塊是晨,每個 CPU 模塊由多個 CPU( 如 4 個 ) 組成,并且具有獨立的本地內存舔箭、 I/O 槽口等罩缴。在一個物理服務器內可以支持上百個 CPU 。但 NUMA 技術同樣有一定缺陷层扶,由于訪問遠地內存的延時遠遠超過本地內存箫章,因此當 CPU 數量增加時,系統(tǒng)性能無法線性增加镜会。
MPP 模式則是一種分布式存儲器模式檬寂,能夠將更多的處理器納入一個系統(tǒng)的存儲器。一個分布式存儲器模式具有多個節(jié)點戳表,每個節(jié)點都有自己的存儲器桶至,可以配置為SMP模式拿诸,也可以配置為非SMP模式。單個的節(jié)點相互連接起來就形成了一個總系統(tǒng)塞茅。MPP可以近似理解成一個SMP的橫向擴展集群亩码,MPP一般要依靠軟件實現。
非一致存儲訪問結構 (NUMA :Non-Uniform Memory Access):它由多個 SMP 服務器通過一定的節(jié)點互聯(lián)網絡進行連接野瘦,協(xié)同工作描沟,完成相同的任務,從用戶的角度來看是一個服務器系統(tǒng)鞭光。其基本特征是由多個 SMP 服務器 ( 每個 SMP 服務器稱節(jié)點 ) 通過節(jié)點互聯(lián)網絡連接而成吏廉,每個節(jié)點只訪問自己的本地資源 ( 內存、存儲等 ) 惰许,是一種完全無共享 (Share Nothing) 結構席覆。
查看你的服務器的 CPU 架構:
2.2 KVM CPU ****虛擬化
2.2.1 KVM ****虛機的創(chuàng)建過程
可見
(1)qemu-kvm 通過對 /dev/kvm 的一系列 ICOTL 命令控制虛機,比如
(2)一個 KVM 虛機即一個 Linux qemu-kvm 進程汹买,與其他 Linux 進程一樣被Linux 進程調度器調度胯陋。
(3)KVM 虛機包括虛擬內存扇调、虛擬CPU和虛機 I/O設備,其中,內存和 CPU 的虛擬化由 KVM 內核模塊負責實現制轰,I/O 設備的虛擬化由 QEMU 負責實現厅缺。
(3)KVM戶機系統(tǒng)的內存是 qumu-kvm 進程的地址空間的一部分供搀。
(4)KVM 虛機的 vCPU 作為線程運行在 qemu-kvm 進程的上下文中郊供。
vCPU、QEMU 進程须揣、LInux 進程調度和物理CPU之間的邏輯關系:
2.2.2 ****因為**** CPU ****中的虛擬化功能的支持盐股,并不存在虛擬的****CPU****,****KVM Guest ****代碼是運行在物理**** CPU ****之上
根據上面的 1.3 章節(jié)耻卡,支持虛擬化的 CPU 中都增加了新的功能疯汁。以 Intel VT 技術為例,它增加了兩種運行模式:VMX root 模式和 VMX nonroot 模式劲赠。通常來講涛目,主機操作系統(tǒng)和 VMM 運行在 VMX root 模式中,客戶機操作系統(tǒng)及其應用運行在 VMX nonroot 模式中凛澎。因為兩個模式都支持所有的 ring,因此估蹄,客戶機可以運行在它所需要的 ring 中(OS 運行在 ring 0 中塑煎,應用運行在 ring 3 中),VMM 也運行在其需要的 ring 中(對 KVM 來說臭蚁,QEMU 運行在 ring 3最铁,KVM 運行在 ring 0)讯赏。CPU 在兩種模式之間的切換稱為 VMX 切換。從 root mode 進入 nonroot mode冷尉,稱為 VM entry漱挎;從 nonroot mode 進入 root mode,稱為 VM exit雀哨】牧拢可見,CPU 受控制地在兩種模式之間切換雾棺,輪流執(zhí)行 VMM 代碼和 Guest OS 代碼膊夹。
對 KVM 虛機來說,運行在 VMX Root Mode 下的 VMM 在需要執(zhí)行 Guest OS 指令時執(zhí)行 VMLAUNCH 指令將 CPU 轉換到 VMX non-root mode捌浩,開始執(zhí)行客戶機代碼放刨,即 VM entry 過程;在 Guest OS 需要退出該 mode 時尸饺,CPU 自動切換到 VMX Root mode进统,即 VM exit 過程±颂可見麻昼,KVM 客戶機代碼是受 VMM 控制直接運行在物理 CPU 上的。QEMU 只是通過 KVM 控制虛機的代碼被 CPU 執(zhí)行馋辈,但是它們本身并不執(zhí)行其代碼抚芦。也就是說,CPU 并沒有真正的被虛級化成虛擬的 CPU 給客戶機使用迈螟。
這篇文章(http://frankdenneman.nl/2013/09/18/vcpu-configuration-performance-impact-between-virtual-sockets-and-virtual-cores/)是關于 vSphere 中 CPU 虛擬化的叉抡,我覺得它和 KVM CPU 虛擬化存在很大的一致。下圖是使用 2 socket 2 core 共 4 個 vCPU 的情形:
幾個概念:socket (顆答毫,CPU 的物理單位)褥民,core (核,每個 CPU 中的物理內核)洗搂,thread (超線程消返,通常來說,一個 CPU core 只提供一個 thread耘拇,這時客戶機就只看到一個 CPU撵颊;但是,超線程技術實現了 CPU 核的虛擬化惫叛,一個核被虛擬化出多個邏輯 CPU倡勇,可以同時運行多個線程)。
上圖分三層嘉涌,他們分別是是VM層妻熊,VMKernel層和物理層夸浅。對于物理服務器而言,所有的CPU資源都分配給單獨的操作系統(tǒng)和上面運行的應用扔役。應用將請求先發(fā)送給操作系統(tǒng)帆喇,然后操作系統(tǒng)調度物理的CPU資源。在虛擬化平臺比如 KVM 中亿胸,在VM層和物理層之間加入了VMkernel層坯钦,從而允許所有的VM共享物理層的資源。VM上的應用將請求發(fā)送給VM上的操作系統(tǒng)损敷,然后操縱系統(tǒng)調度Virtual CPU資源(操作系統(tǒng)認為Virtual CPU和物理 CPU是一樣的)葫笼,然后VMkernel層對多個物理CPU Core進行資源調度,從而滿足Virtual CPU的需要拗馒。在虛擬化平臺中OS CPU Scheduler和Hyperviisor CPU Scheduler都在各自的領域內進行資源調度路星。
KVM 中,可以指定 socket诱桂,core 和 thread 的數目洋丐,比如設置 “-smp 5,sockets=5,cores=1,threads=1”,則 vCPU 的數目為 511 = 5挥等∮丫客戶機看到的是基于 KVM vCPU 的 CPU 核,而 vCPU 作為 QEMU 線程被 Linux 作為普通的線程/輕量級進程調度到物理的 CPU 核上肝劲。至于你是該使用多 socket 和多core迁客,這篇文章 有仔細的分析,其結論是在 VMware ESXi 上辞槐,性能沒什么區(qū)別掷漱,只是某些客戶機操作系統(tǒng)會限制物理 CPU 的數目,這種情況下榄檬,可以使用少 socket 多 core卜范。
2.2.3 ****客戶機系統(tǒng)的代碼是如何運行的
一個普通的 Linux 內核有兩種執(zhí)行模式:內核模式(Kenerl)和用戶模式(User)。為了支持帶有虛擬化功能的 CPU鹿榜,KVM 向 Linux 內核增加了第三種模式即客戶機模式(Guest)海雪,該模式對應于 CPU 的 VMX non-root mode。
KVM 內核模塊作為 User mode 和 Guest mode 之間的橋梁:
User mode 中的 QEMU-KVM會通過 ICOTL 命令來運行虛擬機
KVM 內核模塊收到該請求后舱殿,它先做一些準備工作奥裸,比如將 VCPU 上下文加載到 VMCS (virtual machine control structure)等,然后驅動 CPU 進入 VMX non-root 模式怀薛,開始執(zhí)行客戶機代碼
三種模式的分工為:
Guest 模式:執(zhí)行客戶機系統(tǒng)非 I/O 代碼刺彩,并在需要的時候驅動 CPU 退出該模式
Kernel 模式:負責將 CPU 切換到 Guest mode 執(zhí)行 Guest OS 代碼,并在 CPU 退出 Guest mode 時回到 Kenerl 模式
User 模式:代表客戶機系統(tǒng)執(zhí)行 I/O 操作
QEMU-KVM 相比原生 QEMU 的改動:
原生的 QEMU 通過指令翻譯實現 CPU 的完全虛擬化枝恋,但是修改后的 QEMU-KVM 會調用 ICOTL 命令來調用 KVM 模塊创倔。
原生的 QEMU 是單線程實現,QEMU-KVM 是多線程實現焚碌。
主機 Linux 將一個虛擬視作一個 QEMU 進程畦攘,該進程包括下面幾種線程:
I/O 線程用于管理模擬設備
vCPU 線程用于運行 Guest 代碼
其它線程,比如處理 event loop十电,offloaded tasks 等的線程
在我的測試環(huán)境中(RedHata Linux 作 Hypervisor):
這篇文章(http://blog.chinaunix.net/uid-26000137-id-3761114.html) 談談了這些線程的情況知押。
(圖片來源:http://www.cnblogs.com/popsuper1982/p/3815398.html)
2.2.4 ****從客戶機線程到物理**** CPU ****的兩次調度
要將客戶機內的線程調度到某個物理 CPU,需要經歷兩個過程:
客戶機線程調度到客戶機物理CPU 即 KVM vCPU鹃骂,該調度由客戶機操作系統(tǒng)負責台盯,每個客戶機操作系統(tǒng)的實現方式不同。在 KVM 上畏线,vCPU 在客戶機系統(tǒng)看起來就像是物理 CPU静盅,因此其調度方法也沒有什么不同。
vCPU 線程調度到物理 CPU 即主機物理 CPU寝殴,該調度由 Hypervisor 即 Linux 負責蒿叠。
KVM 使用標準的 Linux 進程調度方法來調度 vCPU 進程。Linux 系統(tǒng)中蚣常,線程和進程的區(qū)別是進程有獨立的內核空間市咽,線程是代碼的執(zhí)行單位,也就是調度的基本單位抵蚊。Linux 中施绎,線程是就是輕量級的進程,也就是共享了部分資源(地址空間贞绳、文件句柄谷醉、信號量等等)的進程,所以線程也按照進程的調度方式來進行調度熔酷。
(1)Linux 進程調度原理可以參考這篇文章(http://www.cnblogs.com/zhaoyl/archive/2012/09/04/2671156.html)孤紧。通常情況下,在SMP系統(tǒng)中拒秘,Linux內核的進程調度器根據自有的調度策略將系統(tǒng)中的一個可運行(runable)進程調度到某個CPU上執(zhí)行号显。下面是 Linux 進程的狀態(tài)機:
(2)處理器親和性:可以設置 vCPU 在指定的物理 CPU 上運行,具體可以參考這篇文章(http://blog.chinaunix.net/uid-26000137-id-3695749.html) 和這篇文章(http://frankdenneman.nl/2011/01/11/beating-a-dead-horse-using-cpu-affinity/)躺酒。
根據 Linux 進程調度策略押蚤,可以看出,在 Linux 主機上運行的 KVM 客戶機的總 vCPU 數目最好是不要超過物理 CPU 內核數羹应,否則揽碘,會出現線程間的 CPU 內核資源競爭,導致有虛機因為 vCPU 進程等待而導致速度很慢。
關于這兩次調度雳刺,業(yè)界有很多的研究劫灶,比如上海交大的論文 Schedule Processes, not VCPUs 提出動態(tài)地減少 vCPU 的數目即減少第二次調度。
另外掖桦,這篇文章(http://www.vmware.com/files/pdf/techpaper/VMware-vSphere-CPU-Sched-Perf.pdf) 談到的是 vSphere CPU 的調度方式本昏,有空的時候可以研究下并和 KVM vCPU的調度方式進行比較。
2.3 ****客戶機****CPU****結構和模型
KVM 支持 SMP 和 NUMA 多CPU架構的主機和客戶機枪汪。對 SMP 類型的客戶機涌穆,使用 “-smp”參數:
對 NUMA 類型的客戶機,使用 “-numa”參數:
CPU 模型(models)定義了哪些主機的 CPU 功能(features)會被暴露給客戶機操作系統(tǒng)雀久。為了在具有不同 CPU 功能的主機之間做安全的遷移宿稀,qemu-kvm 往往不會將主機CPU的所有功能都暴露給客戶機。其原理如下:
你可以運行 qemu-kvm -cpu ?命令來獲取主機所支持的 CPU 模型列表赖捌。
每個Hypervisor 都有自己的策略祝沸,來定義默認上哪些CPU功能會被暴露給客戶機。至于哪些功能會被暴露給客戶機系統(tǒng)巡蘸,取決于客戶機的配置奋隶。qemu32 和 qemu64 是基本的客戶機 CPU 模型,但是還有其他的模型可以使用悦荒。你可以使用 qemu-kvm 命令的 -cpu <model> 參數來指定客戶機的 CPU 模型唯欣,還可以附加指定的 CPU 特性。"-cpu" 會將該指定 CPU 模型的所有功能全部暴露給客戶機搬味,即使某些特性在主機的物理CPU上不支持境氢,這時候QEMU/KVM 會模擬這些特性,因此碰纬,這時候也許會出現一定的性能下降萍聊。
RedHat Linux 6 上使用默認的 cpu64-rhe16 作為客戶機 CPU model:
你可以指定特定的 CPU model 和 feature:
qemu-kvm -cpu Nehalem,+aes
你也可以直接使用 -cpu host,這樣的話會客戶機使用和主機相同的 CPU model悦析。
2.4 ****客戶機**** vCPU ****數目的分配方法
不是客戶機的 vCPU 越多寿桨,其性能就越好,因為線程切換會耗費大量的時間强戴;應該根據負載需要分配最少的 vCPU亭螟。
主機上的客戶機的 vCPU 總數不應該超過物理 CPU 內核總數骑歹。不超過的話预烙,就不存在 CPU 競爭道媚,每個 vCPU 線程在一個物理 CPU 核上被執(zhí)行翘县;超過的話,會出現部分線程等待 CPU 以及一個 CPU 核上的線程之間的切換谴分,這會有 overhead。
將負載分為計算負載和 I/O 負載狸剃,對計算負載狗热,需要分配較多的 vCPU钞馁,甚至考慮 CPU 親和性,將指定的物理 CPU 核分給給這些客戶機匿刮。
這篇文章(http://my.oschina.net/chape/blog/173981)介紹了一些指導性方法,摘要如下:
我們來假設一個主機有 2 個socket熟丸,每個 socket 有 4 個core。主頻2.4G MHZ 那么一共可用的資源是 242.4G= 19.2G MHZ光羞。假設主機上運行了三個VM,VM1和VM2設置為1socket1core呀闻,VM3設置為1socket2core。那么VM1和VM2分別有1個vCPU捡多,而VM3有2個vCPU。假設其他設置為缺省設置垒手。
那么三個VM獲得該主機CPU資源分配如下:VM1:25%倒信; VM2:25%; VM3:50%
假設運行在VM3上的應用支持多線程鳖悠,那么該應用可以充分利用到所非配的CPU資源。2vCPU的設置是合適的竞穷。假設運行在VM3上的應用不支持多線程,該應用根本無法同時使用利用2個vCPU. 與此同時瘾带,VMkernal層的CPU Scheduler必須等待物理層中兩個空閑的pCPU熟菲,才開始資源調配來滿足2個vCPU的需要朴恳。在僅有2vCPU的情況下,對該VM的性能不會有太大負面影響于颖。但如果分配4vCPU或者更多,這種資源調度上的負擔有可能會對該VM上運行的應用有很大負面影響做入。
確定 vCPU 數目的步驟。假如我們要創(chuàng)建一個VM同衣,以下幾步可以幫助確定合適的vCPU數目
1 了解應用并設置初始值
該應用是否是關鍵應用竟块,是否有Service
Level Agreement。一定要對運行在虛擬機上的應用是否支持多線程深入了解耐齐。咨詢應用的提供商是否支持多線程和SMP(Symmetricmulti-processing)浪秘。參考該應用在物理服務器上運行時所需要的CPU個數。如果沒有參照信息埠况,可設置1vCPU作為初始值耸携,然后密切觀測資源使用情況。
2 觀測資源使用情況
確定一個時間段辕翰,觀測該虛擬機的資源使用情況夺衍。時間段取決于應用的特點和要求,可以是數天金蜀,甚至數周。不僅觀測該VM的CPU使用率尝胆,而且觀測在操作系統(tǒng)內該應用對CPU的占用率护桦。特別要區(qū)分CPU使用率平均值和CPU使用率峰值。
假如分配有4個vCPU二庵,如果在該VM上的應用的CPU
使用峰值等于25%催享,也就是僅僅能最多使用25%的全部CPU資源,說明該應用是單線程的因妙,僅能夠使用一個vCPU (4 * 25% =1 )
平均值小于38%票髓,而峰值小于45%铣耘,考慮減少 vCPU 數目
平均值大于75%,而峰值大于90%裆操,考慮增加 vCPU 數目
3 更改vCPU數目并觀測結果
每次的改動盡量少炉媒,如果可能需要4vCPU,先設置2vCPU在觀測性能是否可以接受橱野。
2. KVM ****內存虛擬化
2.1 ****內存虛擬化的概念
除了CPU 虛擬化水援,另一個關鍵是內存虛擬化茅郎,通過內存虛擬化共享物理系統(tǒng)內存,動態(tài)分配給虛擬機系冗。虛擬機的內存虛擬化很象現在的操作系統(tǒng)支持的虛擬內存方式,應用程序看到鄰近的內存地址空間惯豆,這個地址空間無需和下面的物理機器內存直接對應奔害,操作系統(tǒng)保持著虛擬頁到物理頁的映射。現在所有的 x86 CPU 都包括了一個稱為內存管理的模塊MMU(Memory Management Unit)和 TLB(Translation Lookaside Buffer)华临,通過MMU和TLB來優(yōu)化虛擬內存的性能雅潭。
KVM 實現客戶機內存的方式是,利用mmap系統(tǒng)調用扶供,在QEMU主線程的虛擬地址空間中申明一段連續(xù)的大小的空間用于客戶機物理內存映射。
(圖片來源:http://blog.csdn.net/lux_veritas/article/details/9383643 HVA 同下面的 MA太援,GPA 同下面的 PA,GVA 同下面的 VA)
在有兩個虛機的情況下尼荆,情形是這樣的:
可見唧垦,KVM 為了在一臺機器上運行多個虛擬機,需要增加一個新的內存虛擬化層振亮,也就是說坊秸,必須虛擬 MMU 來支持客戶操作系統(tǒng),來實現 VA -> PA -> MA 的翻譯褒搔。客戶操作系統(tǒng)繼續(xù)控制虛擬地址到客戶內存物理地址的映射(VA -> PA)走孽,但是客戶操作系統(tǒng)不能直接訪問實際機器內存琳状,因此VMM 需要負責映射客戶物理內存到實際機器內存(PA ->
MA)。
VMM 內存虛擬化的實現方式:
軟件方式:通過軟件實現內存地址的翻譯念逞,比如 Shadow page table (影子頁表)技術
硬件實現:基于 CPU 的輔助虛擬化功能,比如 AMD 的 NPT 和 Intel 的 EPT 技術
影子頁表技術:
2.2 KVM ****內存虛擬化
KVM 中硕盹,虛機的物理內存即為 qemu-kvm 進程所占用的內存空間审洞。KVM 使用 CPU 輔助的內存虛擬化方式。在 Intel 和 AMD 平臺仰剿,其內存虛擬化的實現方式分別為:
AMD 平臺上的 NPT (Nested Page Tables)技術
Intel 平臺上的 EPT (Extended Page Tables)技術
EPT 和 NPT采用類似的原理痴晦,都是作為 CPU 中新的一層,用來將客戶機的物理地址翻譯為主機的物理地址部凑。關于 EPT, Intel 官方文檔中的技術如下(實在看不懂...)
EPT的好處是涂邀,它的兩階段記憶體轉換,特點就是將 Guest Physical Address → System Physical Address劳较,VMM不用再保留一份 SPT(Shadow Page Table)浩聋,以及以往還得經過 SPT 這個轉換過程。除了降低各部虛擬機器在切換時所造成的效能損耗外墓捻,硬體指令集也比虛擬化軟體處理來得可靠與穩(wěn)定坊夫。
2.3 KSM ****(****Kernel SamePage Merging ****或者**** Kernel Shared Memory****)
KSM 在Linux 2.6.32 版本中被加入到內核中。
2.3.1 ****原理
其原理是践樱,KSM 作為內核中的守護進程(稱為 ksmd)存在,它定期執(zhí)行頁面掃描,識別副本頁面并合并副本屎慢,釋放這些頁面以供它用腻惠。因此,在多個進程中集灌,Linux將內核相似的內存頁合并成一個內存頁。這個特性腌零,被KVM用來減少多個相似的虛擬機的內存占用唆阿,提高內存的使用效率。由于內存是共享的驯鳖,所以多個虛擬機使用的內存減少了久免。這個特性阎姥,對于虛擬機使用相同鏡像和操作系統(tǒng)時鸽捻,效果更加明顯。但是泊愧,事情總是有代價的,使用這個特性屑埋,都要增加內核開銷痰滋,用時間換空間。所以為了提高效率敲街,可以將這個特性關閉。
2.3.2 ****好處
其好處是逻恐,在運行類似的客戶機操作系統(tǒng)時峻黍,通過 KSM,可以節(jié)約大量的內存挽拂,從而可以實現更多的內存超分骨饿,運行更多的虛機。
2.3.3 ****合并過程
(1)初始狀態(tài):
(2)合并后:
(3)Guest 1 寫內存后:
2.4 KVM Huge Page Backed Memory ****(巨頁內存技術)
這是KVM虛擬機的又一個優(yōu)化技術.绒北。Intel 的 x86 CPU 通常使用4Kb內存頁置鼻,當是經過配置,也能夠使用巨頁(huge page): (4MB on x86_32, 2MB on x86_64 and x86_32 PAE)
使用巨頁储藐,KVM的虛擬機的頁表將使用更少的內存,并且將提高CPU的效率钙勃。最高情況下,可以提高20%的效率蔚携!
使用方法克饶,需要三部:
保留一些內存給巨頁
(使用 x86_64 系統(tǒng)時矾湃,這相當于從物理內存中保留了2048 x 2M = 4GB 的空間來給虛擬機使用)
給 kvm 傳遞參數 hugepages
也可以在配置文件里加入:
驗證方式,當虛擬機正常啟動以后霉咨,在物理機里查看:
老外的一篇文檔(http://www.humblec.com/give-hugepage-memory-for-guests/)拍屑,他使用的是libvirt方式,先讓libvirtd進程使用hugepages空間僵驰,然后再分配給虛擬機蒜茴。
作者:劉世民(Sammy Liu)
博客:http://www.cnblogs.com/sammyliu/