80x86機(jī)器的虛擬化最近太火了,不但微軟加入了戰(zhàn)團(tuán),還有一堆Startup搖旗吶喊。那到底哪種虛擬機(jī)好呢?本文就嘗試接著筆者的一些經(jīng)驗(yàn),做一些個(gè)人總結(jié)。
好是一個(gè)相對(duì)的概念。市面上的虛擬機(jī)不但表面上產(chǎn)自不同的公司,其核心實(shí)現(xiàn)技術(shù)也五花八門,適用的場合也千差萬別。一方面你要知道虛擬化技術(shù)能給你帶來什么,一方面你要知道你自己需要什么, 一方面還要知道要達(dá)到你的目標(biāo)選用什么虛擬機(jī),用什么虛擬化戰(zhàn)略最適合你。這個(gè)過程就是選型的過程。希望讀完本文之后,你對(duì)80x86的虛擬化技術(shù)和其發(fā)展現(xiàn)狀能夠有一個(gè)大概的了解。略去虛談虛擬化技術(shù)的好處的文字,讓我們直接來看虛擬機(jī)是怎么實(shí)現(xiàn)的,從而給市面上的虛擬機(jī)做一個(gè)分類。

如果我們重新實(shí)現(xiàn)一個(gè)虛擬機(jī),有好幾種選擇。最直接的選擇是用軟件來模擬硬件。寫一個(gè)簡單的while循環(huán)就可以模擬一個(gè)cpu的工作了:
while (true) {
var instr = GetNextInstruction();
switch (instr) {
case xxx:
// do xxx
case HALT:
return;
}
}
這也是普通的游戲機(jī)模擬器的實(shí)現(xiàn)原理。再加上軟件模擬的外設(shè),比如主板,硬盤什么的。這類虛擬機(jī)叫Enumlator。

Emulator有一個(gè)最大的優(yōu)勢是獨(dú)立于底層硬件。你可以在586上模擬出6502CPU來。這對(duì)于開發(fā)特殊硬件的軟件的工程師特別有用。而由于模擬器的效率低下,最終也只能淪落為調(diào)試工具。為了改進(jìn)性能,人們引入了編譯來代替解釋執(zhí)行。著名的JIT(JVM也算是虛擬機(jī)啊)就是其中的一種,QEMU則是80x86領(lǐng)域的字節(jié)碼編譯的虛擬機(jī)實(shí)現(xiàn)。但是這更多地是一種運(yùn)行時(shí)的優(yōu)化技術(shù),并沒有根本改變其實(shí)現(xiàn),也沒有根本地改變執(zhí)行效率。
根本地解決方案是,不用軟件的循環(huán)去模擬CPU,而是直接使用宿主機(jī)的CPU來執(zhí)行。而且內(nèi)存也不用去模擬,也可以直接用宿主機(jī)的CPU來執(zhí)行。這就是Virtualization技術(shù)。

內(nèi)存是比較容易實(shí)現(xiàn)的,一般都是有一個(gè)映射表來做虛擬內(nèi)存和實(shí)際內(nèi)存地址的映射。這種內(nèi)存虛擬化已經(jīng)是廣泛使用并且非常成熟的技術(shù)。AMD后來提出的虛擬化技術(shù)進(jìn)一步把這種表映射在硬件層面上提供了加速。
問題的難點(diǎn)在于80x86的ring結(jié)構(gòu)上。ring0到ring3,權(quán)限依次遞減。實(shí)際使用中,Windows只利用了ring 0和ring 3兩個(gè)級(jí)別。Guest OS需要運(yùn)行在80x86的Ring 0級(jí)別上。但是Host OS自己已經(jīng)是在80x86的Ring 0級(jí)別上了。虛擬機(jī)作為一個(gè)用戶態(tài)的應(yīng)用程序,只有ring3的特權(quán),這個(gè)狀態(tài)的CPU是不能滿足Guest OS的需要的。這也是為什么80x86虛擬化技術(shù)難以實(shí)現(xiàn)的原因。所以,在最開始的時(shí)候,為了達(dá)到虛擬化的目的,Guest操作系統(tǒng)必須經(jīng)過修改。最開始的時(shí)候Xen就是這么實(shí)現(xiàn)的,需要Guest OS是打過補(bǔ)丁之后的特定版本的Linux。顯而易見,Windows的內(nèi)核是無法被打補(bǔ)丁的。所以,Para-Virtualization只適合開放源代碼或者廠商支持的操作系統(tǒng)。
但是隨著硬件的進(jìn)步。Intel提出了Vt-d技術(shù),Amd提出了Pacifica技術(shù)。雖然名稱不同,但是結(jié)果都是讓ring0之上再多出了一層。從而使得虛擬機(jī)可以欺騙過Guest操作系統(tǒng),讓它認(rèn)為自己就是運(yùn)行在普通的CPU之上。所以Full-Virtualization就出現(xiàn)了。為了利用這些CPU的新技術(shù),它們都有一個(gè)直接貼近硬件的驅(qū)動(dòng)程序,并不是完全基于Host OS之上的。

人類的追求是無止盡的。在把全虛擬化的虛擬機(jī)用在實(shí)戰(zhàn)中,特別是高負(fù)載的服務(wù)器場合之后,很快性能問題就暴露出來。CPU速度是沒有問題的,非常快。問題集中在內(nèi)存消耗和I/O操作速度與隨之而來的CPU占用率的問題。
當(dāng)一臺(tái)機(jī)器能夠安裝多個(gè)虛擬機(jī)之后,人們就想裝盡可能多的虛擬機(jī),從而提高整體的資源利用率。但是由于內(nèi)存的限制,使得這個(gè)單機(jī)負(fù)載的虛擬機(jī)數(shù)量很難提高,同時(shí)內(nèi)存的利用率卻并不高。假設(shè)每個(gè)虛擬機(jī)都分配了1G內(nèi)存,內(nèi)存利用率是60%,那就每臺(tái)有400M的內(nèi)存空閑。一臺(tái)4G的機(jī)器裝了4個(gè)虛擬機(jī),就有1.6G的空閑內(nèi)存。所以裝5臺(tái)虛擬機(jī)是一點(diǎn)問題都沒有的。但是由于每個(gè)虛擬機(jī)都自己捏了一把富余的內(nèi)存在手上以防萬一,導(dǎo)致整體的利用率上不來。為了解決這個(gè)問題,大廠的虛擬機(jī)都有很多優(yōu)化,比如Deflate,Ballooning之類的。而這些優(yōu)化往往是在Guest操作系統(tǒng)上裝一些特殊的驅(qū)動(dòng)程序去控制Guest操作系統(tǒng)的內(nèi)存分配(或者是Linux內(nèi)核的直接支持)。
I/O速度和CPU占用率的問題是由軟件模擬的外設(shè),特別是硬盤和網(wǎng)卡照成的。解決方案自然也是盡可能的利用真實(shí)的硬件。通過給Guest OS上裝優(yōu)化的驅(qū)動(dòng)程序就可以實(shí)現(xiàn)。不過要進(jìn)一步提高性能,就卡在了DMA(Direct Memory Access,直接內(nèi)存訪問)技術(shù)上。DMA是一個(gè)I/O優(yōu)化技術(shù),它可以讓CPU不參與I/O,而外設(shè)直接訪問內(nèi)存。由于內(nèi)存地址是虛擬化的,而DMA是硬件控制的,又無法被修改從而知道虛擬化之后的地址。這個(gè)問題的解決,仍然依賴于Intel、AMD。相信將來會(huì)有支持硬件支持的虛擬I/O的CPU上市。不過從計(jì)劃發(fā)布,到現(xiàn)在我們已經(jīng)等了很久了。

這個(gè)時(shí)候,由于效率的原因Full-Virtualization又變成Para-Virtualization了。因?yàn)镈river也是對(duì)Guest OS的一種修改,不再是透明地虛擬化了。如果對(duì)應(yīng)操作系統(tǒng)沒有驅(qū)動(dòng),你就沒法用(或者說沒法利用優(yōu)化之后的外設(shè)和內(nèi)存)。而這個(gè)對(duì)于Windows來說,又是一個(gè)問題了。KVM至今都沒有發(fā)布Windows的硬盤Virtio驅(qū)動(dòng),導(dǎo)致效率低下。
今天講的是硬件流派,明天繼續(xù)講軟件流派。未完待續(xù)……
浙公網(wǎng)安備 33010602011771號(hào)