[笔记]深入解析Windows操作系统《三》系统机制(七)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: [笔记]深入解析Windows操作系统《三》系统机制

启发式增强(Enlightenment)

启发式增强是Windows虚拟化所采用的一种关键的性能优化手段。它们是对标准的Windows内核代码的直接修改,通过这些修改可以检测到当前操作系统正运行在一个子分区中,从而可以以不同的方式进行工作。通常,这些优化是与硬件高度相关的,它们会导致一次超级调用,以便通知超级监督者。一个例子是,通知超级监督者有一个长的忙等自旋循环。在这种情况下,超级监督者可以让有些状态保持在过时状态,而不是在每一个循环指令都保持最新的状态。进入和退出一个中断状态也可以与超级监督者进行协调,同样地,访问APIC也可以这样,这样的增强可以避免总是捕捉实际的访问然后再对其进行虚拟化。

另一个例子与内存管理有关,特别是TLB刷新和改变地址空间。(有关这些概念的更多信息,请参考本书下册第9章)。通常,操作系统将执行一条CPU指令来刷新这一信息,这会影响整个处理器。然而,因为一个子分区可以与多个其他的子分区共享一个CPU,所以,这样的操作也会为其他这些操作系统刷新这一信息,从而导致可以感知得到的性能退化。如果Windows正运行在一个超级监督者之下,那么,它可以发出一个超级调用,让超级监督者只刷新属于该子分区的特定信息。

硬件仿真和支持

作为一个虚拟化方案,必须也要提供对设备的优化访问。不幸的是,绝大多数设备并没有被设计成可以接受多个来自不同操作系统的请求。超级监督者通过尽可能地提供同一层次的同步机制,以及当实际访问硬件不允许的时候仿真特定设备的做法,来切入这一问题。除了设备以外,内存和处理器也必须被虚拟化。表3.26描述了超级监督者必须要管理的三种硬件。

超级监督者并非将实际的硬件暴露给子分区,而是向其暴露虚拟的设备(称为VDev)。VDev被包装成一些运行在VM辅助进程内的COM组件,它们是位于设备背后的、可以中心化管理的对象。(通常,VDev会暴露一个WMI接口。)Windows虚拟化栈提供了两种虚拟设备的支持:仿真设备(emulated device)和合成设备(synthetic device,也称为enlightened 1/O)。前一种设备为子分区操作系统期望找到的各种设备提供了支持,而后一种设备则要求访客操作系统提供相应的特殊支持。此外,合成设备则通过降低CPU额外负载而获得显著的性能优势。

仿真设备

仿真设备的工作方式是,向子分区展示一组IO端口、内存范围和中断,并且超级监督者可以控制和监视这些端口、内存范围和中断。当检测到对这些资源的访问时,VM辅助进程最终会通过虚拟化栈得到通知(如前面图3.34所示)。然后该进程会仿真什么样的动作在设备上发生,并完成相应的请求,再通过超级监督者往回走,然后到达子分区。仅从这一拓扑视图就可以看出,即使不考虑硬件设备的软件仿真往往很慢这一因素,其间也必有性能损失。

之所以需要仿真设备,源于这样的事实:超级监督者需要支持那些无法感知超级监督者存在的操作系统,以及即便是Windows自身,它的早期安装步骤也需要得到支持。在引导过程中,安装程序不能简单地将子分区需要的所有组件(比如VSC)都加载进来以便使用合成设备,所以,Windows的安装过程总是使用仿真的设备(这也是为什么安装过程显得非常慢,但一旦安装之后,操作系统的运行将会接近于原生系统的速度)。仿真的设备也用于那些并不要求高速仿真的硬件,以及有可能软件仿真更快速的硬件。这包含诸如COM(串行)端口、并行端口或主板本身之类的硬件项目。

注:Hyper-v提供了对Intel i440BX主板、S3 Trio视频卡,以及Intel 21140 NIC的仿真。

合成的设备

尽管对于10Mb的网络连接、低分辨率的VGA显示设备,以及16位的声卡来说,仿真设备已经可以工作得很好了,但是在如今的使用场景下,子分区通常要支持的操作系统和硬件往往要求更高的处理能力,比如支持1000Mb的GbE连接、全彩色高分辨率3D画质,以及高速访问存储设备。

为了在一定的可接受的CPU使用率和虚拟化吞吐量的程度上支持这种虚拟化的硬件访问,虚拟化栈使用了多种组件来优化设备的IO,以达到它们的最佳功能(类似于内核的启发式增强,kernel enlightenment)。这其中包括三个组件,它们都属于对用户来说称为集成组件(IC,integration component)的组件。它们是:

  • 虚拟化服务提供者
  • 虚拟化服务客户/消费者
  • VMBus

图3.37显示的框图展示了一个启发式增强的,或合成的存储IO是如何被虚拟化栈处理的。

如图3.37所示,VSP运行在父分区中,它们在父分区中与一个特定的设备关联起来,设备的启发式增强(enlightening)由相应的VSP负责。(在提到合成的设备[synthetic device]的时候,我们将启发式增强[enlightening]当作一个术语来使用,而不使用仿真[emulating])。VSC驻留在子分区中,也跟一个特定的设备关联起来。然后,请注意,术语提供者(provider)可以指散布在设备栈中的多种组件。

例如,一个VSP可以是下面列举的组件之一:

  • 用户模式服务
  • 用户模式COM组件内核模式驱动程序

在所有这三种情形下,VSP都可以与VM辅助进程中的实际虚拟设备关联起来。而另一方面,VSC则总是被设计成位于设备栈最底层的驱动程序(关于设备栈的更多信息,请参考本书下册第8章),它们截取一个设备的I/O,将这些I/O重定向到一个更优化的路径上。按这种模型执行的主要优化是,避免实际的硬件访问,改而使用VMBus。在这种模型下,超级监督者是不知道这一IO的,VSP将I/O直接定向到父分区的内核存储栈,从而避免了与用户模式的来回通信。其他的VSP可能直接在设备上进行工作,它们与实际的硬件打交道,绕过了父分区上可能已经加载的任何驱动程序。另一种选择是用户模式VSP,当处理低带宽设备的时候,用户模式VSP是有意义的。

正如前面所述,VMBus是用于优化设备访问的总线传输器的名称,其优化的做法是,利用超级监督者的服务来实现一个通信协议。VMBus是一个在父分区和子分区中都存在的总线型驱动程序,负责对子分区中的合成设备进行即插即用列举。它同时也包含了一个优化的跨分区消息传递协议,该消息传递协议采用了一个对于数据大小较为恰当的传输器方法。在这些传输器方法中,其中有一个方法提供了一个在每个分区之间共享的环形缓冲区——本质上,这是一块内存区域,在一端加载特定数量的数据,在另一端卸载相应的数据。在此过程中不需要分配或释放内存,因为该缓冲区是被连续复用的,只是简单地“旋转”而已。最终,该缓冲区可能会填满了各种请求,这意味着新的IO将会覆盖掉老的I/O。在这种不常见的情形下,VMBus只是简单地将新的请求延迟到老的I/O请求完成为止。另一个消息传输器方法是,直接将子内存映射到父地址空间中,以便于大数据量的传输。

虚拟处理器

因为超级监督者不允许直接访问硬件(或内存),稍后我们将会看到,子分区并不会真正看到机器上的实际处理器,但是它们会有一个虚拟化的CPU视图。在根机器上,管理员和操作系统负责处理逻辑处理器(logical processor),这是指线程可直接跑于其上的实际处理器(比如,一个双4核的机器有8个逻辑处理器),同时他们负责将这些逻辑处理器分配给各个子分区。例如,一个子分区可以被安排到逻辑处理器1、2、3和4上运行,而第二个子分区可能被安排到处理器5、6、7和8上运行。通过使用虚拟处理器(VP,virtual processor),这些操作都是有可能的。

因为处理器可以被多个子分区共享,所以,超级监督者包含它自己的调度器,负责在每个处理器上分配各个分区的负载。更进一步,超级监督者也维护了每个虚拟处理器的寄存器状态,当同样的逻辑处理器要被另一个子分区使用的时候,它负责执行一次正确的“处理器切换”。父分区有能力访问所有这些环境信息,并且必要时修改环境信息,这是虚拟化栈中的一个关键部分,它必须响应特定的指令,并执行相应的动作。

超级监督者也直接负责虚拟化处理器的APIC,以及提供一个更简单的、功能少一些的虚拟APIC,其中支持在绝大多数APIC上都可以找到的定时器功能(然而,速率慢一些)。因为并不是所有的操作系统都支持APIC,所以,超级监督者也允许通过一个超级调用来注入中断,这就使得虚拟化栈可以仿真一个标准的i8059 PIC。

最后,因为Windows支持处理器的动态加入,所以,管理员有可能在运行时刻给一个子分区添加新的处理器,因而在负载很重的情况下,可以增强一个访客操作系统的响应能力。

内存虚拟化

必须从子分区中抽象出来的最后一部分硬件是内存,这不仅是为了访客操作系统的正常表现行为,也是为了安全性和稳定性。不正确地管理子分区对内存的访问,有可能导致隐私暴露和数据破坏,以及可能的恶意攻击(比如,通过“脱离”子分区和攻击父分区的做法,再进一步攻击其他的子分区)。除了这一层因素以外,也需要管理访客操作系统所看到的物理地址空间的视图。几乎所有的操作系统都期望内存是从地址0开始的,并且在某种程度上是连续的,所以,即使系统中有足够多的内存,简单地把物理内存块分配给每个子分区并不能工作。

为了解决这个问题,超级监督者实现了一种称为访客物理地址空间(GPA空间,guestphysical address space)的地址空间。GPA从地址0开始,这满足了子分区内部的操作系统的需要。然而,由于第二个问题(缺少连续内存)的原因,GPA并不是简单地映射到一大块物理内存上。相反地,GPA可以指向机器的物理内存(这称为系统物理地址空间,system physicaladdress space,或SPA空间)中的任何位置,因此,从一个地址类型到另一个地址类型,必须要存在一个转译系统。此转译系统是由超级监督者来维护的,几乎等同于在x86和x64处理器上虚拟内存被映射至物理内存的做法。(关于内存管理器和地址转译的更多信息,请参见本书下册第10章。)

对于子分区内的实际虚拟地址(称为访客虚拟地址空间,guest virtual address space,或GVA空间),它们仍然是由操作系统来管理,无需任何行为上的变化。操作系统相信的是,在它的页表中的物理地址是实际的SPA。图3.38概略地显示了每一层映射。

这意味着,当一个访客操作系统引导起来,创建了页表将虚拟内存映射为物理内存的时候,超级监督者截取了SPA,并维护了它自己的页表拷贝。从概念上讲,无论何时当访客操作系统有一段代码要访问一个虚拟地址的时候,超级监督者首先执行初始的页表转译,从访客虚拟地址转译为GPA,然后将GPA映射到相应的SPA。而实际上,这一操作已经利用影子页表( shadow page table,SPT)而进行了优化,这些影子页表是由超级监督者维护的,用于直接从GVA到SPA进行转译,在适当的时候被加载进来,因而访客可以直接访问SPA。

二级地址转译和带标记的TLB

因为从GVA到GPA再到SPA比较昂贵(因为必须由软件来完成),所以,CPU制造商已经做了工作来缓解这部分低效的处理过程,其做法是,让处理器自身能感知到虚拟机的地址转译需求―—换句话说,一个高级的处理器可以理解其内存访问发生在一个访客虚拟机中,并且不依赖于超级监督者的帮助就可以执行GVA-SPA地址查找。这一查找技术被称为二级地址转译(SLAT, Second-Level Address Translation),因为它既包括从目标到宿主的转译(第二级),也包括从宿主VA到宿主PA的转译(第一级)。然而,出于市场的意图,Intel将这一支持称为VT扩展/嵌套的页表(NPT,Nested Page 'Table)技术,而AMD将其称为AMD-V快速虚拟化索引(AMD-V Rapid Virtualization Indexing,RVD

Hyper-V栈的最新版本充分利用了处理器的这一支持技术,大大降低了其代码的复杂程度,并且使得子分区中因处理页面错误而需要的环境切换数量降低到最小。而且,SLAT也使得Hyper-V能够扔掉它的影子页表和相关的映射关系,这本身也额外地降低了内存开销。这些变化增加了Hyper-V在这些系统上的伸缩能力,显著地增加了单个宿主(Hyper-V服务器)可以服务(或者可以同时运行的)的虚拟机的最大数量。根据Microsoft所做的测试,SLAT的支持使得所支持的会话最大数量提高了16至25倍。更进一步,处理器的额外开销从10%降低到2%,每个虚拟机消耗的宿主物理RAM少于1兆字节。

而且,Intel和AMD都引入了一种通常只在RISC处理器(比如ARM、MIPS或PPC)上才有的功能,即处理器能够区分与TLB(地址转译快查缓冲区)中每个缓存的虚拟-物理转译项相关联的进程。在像x86和x64这样的CISC处理器上,TLB被内置成一个全系统范围的资源―一每次当操作系统切换当前正在执行的进程时,TLB必须被刷新,以便让所有可能属于前一个执行进程的缓存项无效。反之,如果处理器可以被告知当前进程已经改变了,那么,TLB可以避免一次刷新,处理器只需简单地不用这些与当前进程没有对应关系的缓存项即可。新的缓存项将会创建起来,最终会覆盖其他进程的老项。这种类型的智能TLB被称为带标记的TLB( tagged TLB),因为每个缓存项都有一个属于特定进程的标识符作为标记。

对于Hyper-V系统,刷新TLB尤其糟糕,因为不同的进程可能实际上对应于一个完全不同的VM。换句话说,每次当超级监督者和操作系统调度另一个VM来执行时,宿主的TLB必须被刷新,把前一个VM已经执行过的所有缓存起来的转译项都刷掉了,从而显著减慢内存访问,导致明显的延迟。当在一个实现了带标记的TLB的处理器上运行时,Hyper-V可以简单地通知处理器,有一个新的进程/VM正在运行,其他VM的缓存项不应该使用了。有RVI支持的AMD处理器通过一个地址空间标识符(ADIS,Address Space ldentifier)来支持带标记的TLB,而最新的Intel Nehalem-EX处理器使用虚拟处理器标识符(VPID,Virtual Processor Ildentifier)来实现带标记的TLB。

动态内存

一个称为动态内存的特性使得系统管理员可以让一个虚拟机的物理内存分配根据活动的虚拟机的内存需求来动态地变化,其做法如同Windows内存管理器根据各个进程的内存需求来调整每个进程被分配到的物理内存。这种能力意味着,管理员不必为了优化性能而精确地测量虚拟机的内存需求,并且系统的物理内存可以被真正需要内存的虚拟机更加有效地使用。

动态内存的体系结构包括几个组件,如图3.39所示。

此体系结构的基本组件如下所述:

  • 动态内存平衡器,是在虚拟机管理服务中实现的。此平衡器负责为子分区分配物理
    内存。
  • 动态内存VSP (DM VSP),它运行在已经启用了动态内存的子分区的VMWP中。
  • 动态内存VSC (DM VSC,%SystemRoot%lSystem32\Drivers\Dmvsc.sys),被安装为一个启发式增强驱动程序,在子分区中运行。

要想配置VM的动态内存,管理员可以在VM的内存设置中选择Dynamic,如图3.40所示。

相关的设置包括,当启动时候分配给该VM的内存数量、最大可为它分配的数量(MaximumRAM)、如果操作系统的内存需求增加了它立即可以使用的VM内存占到多少百分比,最后,这个VM相对于其他VM的权重。超级监督者除了要权衡那些启用了动态内存的虚拟机之间的物理内存分布以外,也使用该权重作为系统引导时候这些虚拟机的启动顺序的一个指导。最后,可用内存百分比是指,在VM内部VM操作系统尚未分配给进程、设备驱动程序或其自身的内存的一个参考,这些内存可立即分配而不会招致页面错误。关于可用内存,本书下册第10章有更为详细的描述。

当一个在内存配置中已经启用了动态内存的子分区中的DM VSC启动的时候,它首先进行检查,看操作系统是否支持动态内存的能力。它执行这一检查的做法很简单,只是调用内存管理器中热加入(hot-add)的内存函数,指定一块已经分配给该虚拟机的子物理内存块。如果内存管理器支持热加入(hot-add),它返回一个错误,指明此地址范围已经在使用了;如果它不支持,则会报告该函数不支持。如果支持动态内存,则DM VSC通过VMBus建立起与DMVSP之间的连接。因为系统在引导过程中内存使用情况波动很大,所以,在所有自启动的Windows服务已经完成初始化以后,VSC才开始报告内存统计情况,一秒钟一次,指示出虚拟机中的当前系统内存提交级别(system commit level)。有关系统内存提交的更多信息,参见本书下册第10章。

父分区中的DM VSP根据VM的内存报告,利用下面的公式,为它对应的VM计算一个内存压力值:

内存压力=已提交的内存/物理内存

物理内存指的是当前分配给此VM分区的内存总数。它也维护了一个正在运行的指数平均压力,代表了此前20秒的压力报告,并且只有当当前压力偏离平均值至少一个标准偏差的时候才调整平均压力。

一个称为平衡器的组件在VMMS服务中执行。它每秒钟一次分析由DM VSP报告的内存压力,并考虑到VM策略配置,来决定是否应该要重新分配内存,以及重新分配多少内存。如果一个称为NUMA散布(NUMA spanning)的全局Hyper-V设置被启用的话,平衡器使用两个平衡引擎:一个引擎是全局平衡器,它负责将新的VM分配到NUMA节点上。它在分配的时候根据内存使用量和VM压力来做到这一点。每个NUMA节点有它自己的本地平衡器,管理所有分配给它的VM之间的节点内存分配情况。如果NUMA散布选项没启用,则全局平衡器仅仅只是调用系统的本地平衡器,没有其他的功能角色。

将VM分配到NUMA节点,带来的好处是,VM将保证有尽可能最快的内存访问。然而,也需要做出妥协,在特定情况下,虽然未分配的内存是足够的,但是没有一个节点有足够的内存来满足所请求的内存数量,那么,可能无法启动一个VM,或者为它增加内存。

一个本地平衡器增加或降低全局的目标内存压力,以便使用所有在它管理下的可用内存,或者直至达到最小的压力级别(表明所有的VM都有充足的内存)才使用它。然后,平衡器在VM上进行循环,确定从每个VM中增加或移除多少内存可以达到目标压力。在计算过程中,平衡器为宿主系统保留一个最小的内存数量。宿主系统保留的内存数量是这样来计算的,大约400MB为一个基数,再每1GB RAM增加30MB。可能会影响保留内存数量的因素有:系统是否使用SLAT或软件换页,多媒体重定向是否已启用。每隔5分钟,平衡器也要从那些有了足够多内存以至于其压力值基本为0的VM中移除内存。

注意,如果子分区的操作系统正在运行32位版本的Windows,那么,动态内存引擎将不会为该分区分配超过4GB内存。

一旦已经计算出要从VM中增加或移除的内存数量,它就请每个WP执行所期望的操作。如果此操作是移除内存,那么WP通过VMBus向子DM VSC发送信号,告诉它要移除内存的数量,DM VSC通过MmAllocatePagesForMdlEx函数从系统申请物理内存,以此来膨胀它的内存使用量。它获得所分配的GPA,并送回给WP,WP又把这些GPA传递给Hyper-V内存管理器。Hyper-V内存管理器然后又把GPA转换成SPA,并且将这些内存加入到它的空闲内存池中。

如果这是一个内存增加操作,那么WP首先问Hyper-V内存管理器,该VM是否有已经赋予了它但当前已被VSC的膨胀操作(VSC’s balloon)而分配掉的任何物理内存。如果有的话,则WP获取应该被解除膨胀(unballooned)数量的GPA,请VSC释放这些页面,使它们又可用于VM的操作系统。如果因解除膨胀而释放的内存数量少于平衡器想要交给此VM的物理内存数量,那么,它通过Windows对热增加(hot-add)内存的支持,请Hyper-V内存管理器从它的空闲内存池中把剩余数量的内存交给此子分区,并且把它增加的GPA报告给WP,WP又会依次转发给子分区的DM VSC.

实验:观察动态内存

中断

我们已经讨论了超级监督者对硬件、处理器和内存访问进行虚拟化的各种方法,有时候这些过程需要转交给一个VM辅助进程,但是,我们尚未讨论到使这些虚拟化赖以实现的一种机制―—中断。中断是可配置的“钩子(hook)”,父分区可以安装和配置来响应中断。这可以包括以下的一些项目:

  • IO中断,用于设备仿真。
  • MSR中断,用于APIC仿真和性能剖析。
  • 访问GPA,有助于设备仿真、监视和性能剖析(而且,这样的中断可以针对一个特定的内存访问进行微调,比如读、写或执行)。
  • 异常中断,比如页面错误,有助于维护机器的状态和内存仿真(比如,维护写时复制(copy-on-write))。

一旦超级监督者检测到一个已经注册了相应中断的事件,它通过虚拟化栈发送一个中断消息,将虚拟处理器(VP)置于一种挂起的状态。然后,虚拟化栈(往往是辅助进程)必须处理该事件,并且恢复VP(通常一个寄存器状态已被修改,反映出为处理该中断而执行了相应的工作。)

热迁移

为了支持诸如有计划的硬件升级和跨服务器的资源负载平衡之类的场景,Hyper-V也支持在一个Windows Failover Cluster的节点之间以最小的宕机时间来迁移虚拟机。热迁移效率的关键之处在于,当虚拟机继续在源节点上运行的时候有大量的虚拟机内存要从源节点传输到目标节点上;只有当内存传输完成以后,该虚拟机才挂起,并且在目标节点上恢复运行。当最终的虚拟机状态迁移的时候,这一小窗口通常小于默认的TCP超时值,因而可以为那些使用虚拟机服务的客户保留住它们的已打开连接,使得整个迁移过程从它们的角度来看是透明的。图3.41显示了热迁移过程。

热迁移过程按照几个步骤来进行,如图3.41所示:

  1. 设置迁移虚拟机宿主(源)节点的VMMS打开一个TCP连接,连接至目标主机。它
    将虚拟机的配置信息传输至目标节点,包括诸如处理器个数、RAM数量之类的虚拟硬件规格参数。目标节点上的VMMS构造一个符合此配置但已停住的虚拟机。源节点的VMMS通知虚拟机的辅助进程,此热迁移已经可以进行了,并且将TCP连接交给它。同样地,目标VMMS把它的TCP连接端点交给目标辅助进程。
  2. 内存传输内存传输阶段包括以下几个子阶段:
    (1) 源VMWP创建一个位图,其中每一位代表了虚拟机的访客物理内存中的每一个
    页面。它设置好每一位,以反映出该页面是脏的,即该页面的当前内容尚未被发送至目标节点。
    (2) 源VMWP向超级监督者注册一个内存变化通知回调,该回调函数会为虚拟机中
    每一个发生变化的页面在位图中设置相应的位。
    (3)源VMWP继续处理,按照16-KB内存块来遍历脏页面位图,为内存块中的页面清
    除掉在脏页面位图中的脏位,通过超级监督者来读取每一个脏页面的内容,再将这些内容发送至目标节点。目标VMWP调用超级监督者,将内存的内容插入到目标虚拟机的访客物理内存中。
    (4)当遍历完成了脏页面位图以后,源VMWP检查一下看是否在迭代过程中有页面被弄脏了。如果没有,则转移到迁移过程中的下一个阶段,但如果有页面被弄脏,那么,它重复上述迭代过程。如果已经迭代了5次,说明虚拟机当前弄脏内存的速度比辅助进程发送内存变化信息的速度还要快,因此它也继续向前,转到迁移过程的下一个阶段。
  3. 状态传输源VMWP挂起虚拟机,对脏页面位图作最后一遍迭代,把上次遍历以来的
    所有弄脏的页面都发送过去。因为在传输过程中虚拟机被挂起了,所以,不会再有其他页面被弄脏。然后,源辅助进程发送虚拟机的状态,包括虚拟处理器的寄存器内容。最后,它通知VMMS,迁移过程已经完成,等待确认,然后向目标发送一个消息,把虚拟机的所有权传递过去。作为最后的迁移步骤,目标辅助进程将虚拟机转移到运行状态。
  4. 热迁移的另一个方面是,虚拟机中的文件的所有权转移,包括它的VHD。传统的Windows Clustering是一个“什么也不共享(shared-nothing)”的模型,集群存储系统的每一个LUN一次只归属于一个节点。LUN所属节点对LUN和其中存储的文件有专属的访问权。这种模型带来了管理上的复杂性,因为每个虚拟机必须被存储在一个独立的LUN上,因此也一定在一个单独的卷上,这就使得,若一个集群中宿纳了许多虚拟机,则这些卷就要暴露出来。对于热迁移,这也带来了一个更加严重的挑战,
    因为LUN所有权的迁移是一个很昂贵的操作,包括:源节点将所有修改的文件数据刷新到LUN上,源节点把在LUN上格式化的卷都要解除挂载(unmounting),把所有权从源节点转移到目标节点,再在目标节点上挂载相应的卷。根据LUN上卷的数量以及要被写回的脏数据的数量的不同,这整个序列可以要花几十秒钟,从而使得热迁移无法满足“感觉上近乎瞬间完成迁移”的目标。
  5. 为了解决传统集群模型的限制,使得热迁移真正成为可能,热迁移采用了一种称为
    集群共享卷(CSV,Clustered Shared Volume)的存储特性。通过CSV,一个节点拥有LUN上卷的名字空间,而其他的节点可以独占拥有单独的文件。这种独占所有权使得存放虚拟机的节点可以直接访问VHD文件的磁盘存储,从而绕过了为与其他节点所属LUN打交道而要求的网络文件系统访问。只有当一个节点想要创建或删除文件、改变文件的大小(比如,扩展一个动态的或差分式VHD的大小)、或者改变其他文件元数据(比如时间戳)的时候,它才需要通过SMB2协议向所属节点发送一个请求(如果它不是文件的所有者的话)。
  6. CSV的混合共享模型使得LUN所有权在热迁移过程中保持不变,仅仅使要迁移的虚
    拟机文件的所属权发生了变化,这样就避免了解除挂载和重新挂载的操作。而且,只有虚拟机文件的脏数据必须要在迁移之前写入,这一动作通常可以与内存迁移同时进行。图3.42显示了在一次热迁移过程中存储所有权的变化。本书下册第12章“文件系统”的“文件系统过滤型驱动程序”一节讲述了CSV的实现。

相关文章
|
3天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
14 2
|
15天前
|
存储 负载均衡 Java
如何配置Windows主机MPIO多路径访问存储系统
Windows主机多路径(MPIO)是一种技术,用于在客户端计算机上配置多个路径到存储设备,以提高数据访问的可靠性和性能。本文以Windows2012 R2版本为例介绍如何在客户端主机和存储系统配置多路径访问。
57 13
如何配置Windows主机MPIO多路径访问存储系统
|
3天前
|
网络协议 网络安全 网络虚拟化
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算。通过这些术语的详细解释,帮助读者更好地理解和应用网络技术,应对数字化时代的挑战和机遇。
20 3
|
5天前
|
Windows Python
如何反向读取Windows系统日志EVTX文件?
以下是如何反向读取Windows系统日志EVTX文件
15 2
|
5天前
|
存储 消息中间件 算法
深入探索操作系统的心脏——内核机制解析
本文旨在揭示操作系统核心——内核的工作原理,通过剖析其关键组件与机制,为读者提供一个清晰的内核结构图景。不同于常规摘要的概述性内容,本文摘要将直接聚焦于内核的核心概念、主要功能以及其在系统管理中扮演的角色,旨在激发读者对操作系统深层次运作原理的兴趣与理解。
|
17天前
|
存储 缓存 安全
🌟Java零基础:深入解析Java序列化机制
【10月更文挑战第20天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
21 3
|
22天前
|
Java 开发者 UED
Java编程中的异常处理机制解析
在Java的世界里,异常处理是确保程序稳定性和可靠性的关键。本文将深入探讨Java的异常处理机制,包括异常的类型、如何捕获和处理异常以及自定义异常的创建和使用。通过理解这些概念,开发者可以编写更加健壮和易于维护的代码。
|
16天前
|
机器学习/深度学习 Android开发 UED
移动应用与系统:从开发到优化的全面解析
【10月更文挑战第25天】 在数字化时代,移动应用已成为我们生活的重要组成部分。本文将深入探讨移动应用的开发过程、移动操作系统的角色,以及如何对移动应用进行优化以提高用户体验和性能。我们将通过分析具体案例,揭示移动应用成功的关键因素,并提供实用的开发和优化策略。
|
29天前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
28 0
|
30天前
|
Windows
.NET 隐藏/自定义windows系统光标
【10月更文挑战第20天】在.NET中,可以使用`Cursor`类来控制光标。要隐藏光标,可将光标设置为`Cursors.None`。此外,还可以通过从文件或资源加载自定义光标来更改光标的样式。例如,在表单加载时设置`this.Cursor = Cursors.None`隐藏光标,或使用`Cursor.FromFile`方法加载自定义光标文件,也可以将光标文件添加到项目资源中并通过资源管理器加载。这些方法适用于整个表单或特定控件。

推荐镜像

更多