我们使用了同样的基本方法来构建Xen。Xen就是以整个操作系统的粒度复用物理资源,它能够提供在操作系统间的性能隔离。相对于进程级的资源复用,Xen要允许一定范围内的guest OS“和平”共存,而并非去指定一个特殊的应用二进制接口(//如果限定了应用二进制接口,就意味着只能支持某个特定的操作系统)。为了获得这种灵活性就必须付出一些代价 — 无论是在初始化过程(比如,boot和resume与fork和exec的比较)中,还是在资源消费上,运行一个完整的操作系统与运行一个进程相比分量都要重得多。
为了达到我们的能够支持多至100个被操控的操作系统实例的目标,我们认为这些代价是值得付出的。付出这些代价后获得的系统允许单个用户在资源受控的形式下,直接运行那些不需要修改的二进制代码或者二进制代码集合(例如,后端为PostgreSQL的Apache服务器)。更进一步的,因为用户能够动态地精确创建他们的软件所需要的执行环境,所以这个系统也就提供了在非常高的层次上的灵活性。另外,在各种服务和应用间的配置交互也是可以避免的(例如,每个Windows实例都有它们自己的寄存器文件)。
本文的余下部分是这样组织的:第2部分解释了我们的虚拟化方法和Xen的工作概况。第3部分描述了我们的设计和实现的关键特征。第4部分给出了使用业界标准的测试程序评估运行在Xen上的XenoLinux与单独的Linux,VMware Workstation和用户模式Linux(UML)的性能比较结果。最后的第5部分讨论了未来的工作并作了总结。
2. XEN:方法和概述
在传统的VMM中,虚拟硬件的功能是与底层机器上的真实硬件完全相同的。这种“完全虚拟化”(full virtualization)的方法最显而易见的好处在于操作系统可以不经任何修改就直接在虚拟硬件上运行,但是它也有很多缺点。特别是针对那些当前被广泛应用的IA32(或者称作x86)架构,这种方法带来的缺陷更是不容忽视。
x86架构的设计从来就不支持完全的虚拟化。如果要正确实现x86架构虚拟化,VMM就必须能够对某几条特定的“超级指令(supervisor instruction)”进行操作。但是,如果在没有足够特权的情况下执行这些超级指令会导致“沉默的失败(//fail silently:如果特权级不够,那么会直接导致执行失败,不会产生其它响应)”,而并非产生一个便于我们使用的陷阱(trap)。
另外,将x86架构中的MMU进行有效的虚拟化也是一件很困难的事情。这些问题是可以被解决的,但是在解决的同时必须要付出操作复杂度增加和系统性能降低的代价。VMware ESX Server[10]需要动态地重写那些被VMM操控的机器码部分,在其中有可能需要VMM干涉的地方插入陷阱操作(//在什么地方插入陷阱操作,是在程序运行起来后才知道的,所以需要动态地重写相关代码)。因为务必要对所有那些不能够引起陷阱的特权指令进行捕捉和操作,所以这种转换(//动态重写代码)要被应用于整个guest OS的内核(导致了相关的转换,执行和缓存等开销)。ESX Server实现中采用的技术是建立系统结构(system structure)(比如页表)的影子版本,通过为每一次“更新”操作设立陷阱来解决虚拟页表和物理页表的一致性问题(//具体细节还是要看ESX Server的说明)。但是在处理“更新密集”型的操作(如创建新的应用进程)的时候,该方法会带来高昂的开销。
除了x86架构非常复杂的原因,还有一些其它方面的争论反对“完全虚拟化”。其中值得一提的是,被操控的操作系统在一些情况下需要接触到真实的资源。例如,提供真实时间和虚拟时间以允许guest OS能够更好地支持“时间敏感”型的任务,还可以正确地操作TCP超时和RTT估算;给出真实的机器地址以允许guest OS能够利用超级页(superpage)或者页染色(page coloring)等方法改进性能。
我们提出的虚拟机抽象能够避免完全虚拟化带来的种种缺陷。这种虚拟机抽象和底层硬件相似却并不完全相同,因此被称之为“准虚拟化”(//paravirtualization:或者翻译为半虚拟化?后面译文沿用准虚拟化)方法。这种方法虽然需要对guest OS进行一些改动,但是它能够改善性能。还有特别重要的一点需要说明:准虚拟化方法不会对应用二进制接口(ABI)进行修改,因此用户也就不用修改那些在guest OS上执行的应用程序。
最新相关文章
发表评论