我應該用哪種虛擬機?(一)
系列文章導航:
80x86機器的虛擬化最近太火了,不但微軟加入了戰團,還有一堆Startup搖旗吶喊。那到底哪種虛擬機好呢?本文就嘗試接著筆者的一些經驗,做一些個人總結。
好是一個相對的概念。市面上的虛擬機不但表面上產自不同的公司,其核心實現技術也五花八門,適用的場合也千差萬別。一方面你要知道虛擬化技術能給你帶來什么,一方面你要知道你自己需要什么, 一方面還要知道要達到你的目標選用什么虛擬機,用什么虛擬化戰略最適合你。這個過程就是選型的過程。希望讀完本文之后,你對80x86的虛擬化技術和其發展現狀能夠有一個大概的了解。略去虛談虛擬化技術的好處的文字,讓我們直接來看虛擬機是怎么實現的,從而給市面上的虛擬機做一個分類。
如果我們重新實現一個虛擬機,有好幾種選擇。最直接的選擇是用軟件來模擬硬件。寫一個簡單的while循環就可以模擬一個cpu的工作了:
while (true) { var instr = GetNextInstruction(); switch (instr) { case xxx: // do xxx case HALT: return; } }
這也是普通的游戲機模擬器的實現原理。再加上軟件模擬的外設,比如主板,硬盤什么的。這類虛擬機叫Enumlator。
Emulator有一個最大的優勢是獨立于底層硬件。你可以在586上模擬出6502CPU來。這對于開發特殊硬件的軟件的工程師特別有用。而由于模擬器的效率低下,最終也只能淪落為調試工具。為了改進性能,人們引入了編譯來代替解釋執行。著名的JIT(JVM也算是虛擬機啊)就是其中的一種,QEMU則是80x86領域的字節碼編譯的虛擬機實現。但是這更多地是一種運行時的優化技術,并沒有根本改變其實現,也沒有根本地改變執行效率。
根本地解決方案是,不用軟件的循環去模擬CPU,而是直接使用宿主機的CPU來執行。而且內存也不用去模擬,也可以直接用宿主機的CPU來執行。這就是Virtualization技術。
內存是比較容易實現的,一般都是有一個映射表來做虛擬內存和實際內存地址的映射。這種內存虛擬化已經是廣泛使用并且非常成熟的技術。AMD后來提出的虛擬化技術進一步把這種表映射在硬件層面上提供了加速。
問題的難點在于80x86的ring結構上。ring0到ring3,權限依次遞減。實際使用中,Windows只利用了ring 0和ring 3兩個級別。Guest OS需要運行在80x86的Ring 0級別上。但是Host OS自己已經是在80x86的Ring 0級別上了。虛擬機作為一個用戶態的應用程序,只有ring3的特權,這個狀態的CPU是不能滿足Guest OS的需要的。這也是為什么80x86虛擬化技術難以實現的原因。所以,在最開始的時候,為了達到虛擬化的目的,Guest操作系統必須經過修改。最開始的時候Xen就是這么實現的,需要Guest OS是打過補丁之后的特定版本的Linux。顯而易見,Windows的內核是無法被打補丁的。所以,Para-Virtualization只適合開放源代碼或者廠商支持的操作系統。
但是隨著硬件的進步。Intel提出了Vt-d技術,Amd提出了Pacifica技術。雖然名稱不同,但是結果都是讓ring0之上再多出了一層。從而使得虛擬機可以欺騙過Guest操作系統,讓它認為自己就是運行在普通的CPU之上。所以Full-Virtualization就出現了。為了利用這些CPU的新技術,它們都有一個直接貼近硬件的驅動程序,并不是完全基于Host OS之上的。
人類的追求是無止盡的。在把全虛擬化的虛擬機用在實戰中,特別是高負載的服務器場合之后,很快性能問題就暴露出來。CPU速度是沒有問題的,非常快。問題集中在內存消耗和I/O操作速度與隨之而來的CPU占用率的問題。
當一臺機器能夠安裝多個虛擬機之后,人們就想裝盡可能多的虛擬機,從而提高整體的資源利用率。但是由于內存的限制,使得這個單機負載的虛擬機數量很難提高,同時內存的利用率卻并不高。假設每個虛擬機都分配了1G內存,內存利用率是60%,那就每臺有400M的內存空閑。一臺4G的機器裝了4個虛擬機,就有1.6G的空閑內存。所以裝5臺虛擬機是一點問題都沒有的。但是由于每個虛擬機都自己捏了一把富余的內存在手上以防萬一,導致整體的利用率上不來。為了解決這個問題,大廠的虛擬機都有很多優化,比如Deflate,Ballooning之類的。而這些優化往往是在Guest操作系統上裝一些特殊的驅動程序去控制Guest操作系統的內存分配(或者是Linux內核的直接支持)。
I/O速度和CPU占用率的問題是由軟件模擬的外設,特別是硬盤和網卡照成的。解決方案自然也是盡可能的利用真實的硬件。通過給Guest OS上裝優化的驅動程序就可以實現。不過要進一步提高性能,就卡在了DMA(Direct Memory Access,直接內存訪問)技術上。DMA是一個I/O優化技術,它可以讓CPU不參與I/O,而外設直接訪問內存。由于內存地址是虛擬化的,而DMA是硬件控制的,又無法被修改從而知道虛擬化之后的地址。這個問題的解決,仍然依賴于Intel、AMD。相信將來會有支持硬件支持的虛擬I/O的CPU上市。不過從計劃發布,到現在我們已經等了很久了。
這個時候,由于效率的原因Full-Virtualization又變成Para-Virtualization了。因為Driver也是對Guest OS的一種修改,不再是透明地虛擬化了。如果對應操作系統沒有驅動,你就沒法用(或者說沒法利用優化之后的外設和內存)。而這個對于Windows來說,又是一個問題了。KVM至今都沒有發布Windows的硬盤Virtio驅動,導致效率低下。
今天講的是硬件流派,明天繼續講軟件流派。未完待續……