KTurnura / paper-notes

1 stars 0 forks source link

The design of a practical system for fault-tolerant virtual machines #4

Open KTurnura opened 8 months ago

KTurnura commented 8 months ago

Vmware公司在虚拟机上实现分区容错性

KTurnura commented 8 months ago

backup VM复制primary VM操作,实现了具有分区容错、企业级别的商业系统。设计并实现了一些组件,可以在故障后自动恢复冗余,构造了一个可用,高效的系统

使用最常见的primary/backup方式来实现容错,使用状态机来完成primary/backup同步:通过相同状态启动,并且确保他们以相同顺序接受相同输入请求,但有些操作是不确定的:读取时钟或发送中断。 而且被用来保证backup和primary同步所需的额外消息远远小于交互两者信息所需要的数量.

这种方法在现实物理机器上很难实现协调同步,但在Vmware这种运行在一个hypervisor之上特定的虚拟机中,却是一个很好的平台

hypervisor:可以实现一个对VM的完全控制,可以捕获在primary上所有不确定操作的必要信息,并且在backup上正确的重演 ,为了提供硬件容错性,该系统通过在任意一个本地可用服务器上启动一个新的backupVM来自动恢复冗余

KTurnura commented 7 months ago

同步方式

基于执行日志,但添加了必要的额外协议,构建了一个完全容错的系统

限制

只支持单处理机器

仅处理fail-stop错误

特点 / 创新点

  1. 基于共享存储,所有Client只与primary沟通,包括输入和输出

  2. 使用logging channel 传递primary/backup 日志,backup执行日志中包含有输出的命令同样有输出,但被hypervisor删除

  3. Section 2.2 讲述了primary和backup之间遵守的协议,在primary 的output输出之前先向backup发送一个请求,发送本次output 操作相关的命令,接收到backup回应后在执行输出,这样故障恢复时,backup都能同步到故障前一次输出一致状态机节点

  4. 命令的重做抽象为确定状态机:

If two deterministic state machines are started in the same initial state and provided the exact same inputs in the same order, then they will go through the same sequences of states and produce the same outputs

  1. 使用心跳机制检测P/B是否出错,监控logging channel 流量,故障时及时启动备用接管,由于任何错误检测方法都对脑裂问题敏感,论文使用共享存储来避免脑裂问题,当primary 或者 backup VM想要 主持活动时,他们将执行一次原子性 test-and-set操作在共享的存储上

    但也需要考虑异常发生在共享存储上的情况,

    使用共享存储来解决脑裂情景将不会引入任何额外的可用性

  2. 实现了primary启动一个新的backup VM 的机制,该机制不会显著中断主虚拟机的执行

  3. 在logging channel上设置了一个buffer 区域,还设计了一个组件来最小化primary buffer溢出:==我们使用一个slow feedback loop 来均衡primary 和 backup的同步速度,lag时间既不太长,也不能太短==,理论上要求backup 需要和primary 保持相同的执行速率

  4. VMware FT 确保两个虚拟机都不会移动到另一个虚拟机所在的服务器,因为这种情况将不再提供容错能力

    使用VMotion同时对backup和primary进行独立处理:比如同时停止backup和primary,或者同时增加CPU核数

  5. 磁盘操作设置为非阻塞,所以可以并行的执行,我们Disk IO的实现直接使用DMA来进出虚拟机内存,所以链接相同内存页的磁盘操作也会导致不确定性

    解决办法是,通常是用于检测任何此类IO竞争(其实很少见),然后强制这些竞争磁盘的操作在primary 和 backup 上顺序的执行

  6. 同时统一服务器上的不同应用可能也存在磁盘操作和内存访问竞争,因为disk 通过DMA 直接访问一个VM的内存,一种解决方案是在作为磁盘操作目标的页面上临时设置页面保护,但执行这种操作开销比较大。在本文中,使用bounce buffer来代替页面保护

  7. 当primary发送错误,bakcup接管时,新升级的主虚拟机无法确定磁盘 IO 是否已发送到磁盘或是否成功完成新升级的主虚拟机无法确定磁盘 IO 是否已发送到磁盘或是否成功完成

    我们可以发送一个错误完成来指示每个 IO 失败,因为即使 IO 成功完成,返回错误也是可以接受的,我们在备份虚拟机上线过程中重新发出挂起的 IO。即使这些磁盘操作已经成功完成,也可以重新执行(即它们是幂等的)

  8. 容错网络仿真代码的最大变化是禁用了异步网络优化

    我们使用了两种提高VM网络性能(消除网络设备的异步更新以及第 2.2 节中描述的延迟发送数据包给primary网络带来了一些性能挑战)的方法:

    1. 我们实现了集群优化来降低VM traps 和 中断的次数

      1. 当虚拟机以足够的比特率传输数据时,管理程序可以为每组数据 包执行一个传输陷阱,并且在最好的情况下为零陷阱,因为它可以将 数据包作为接收新数据包的一部分进行传输
        1. 对于传入数据包,仅发布一组数据包的中断
    2. 减缓传输数据包带来的延迟

      1. 我们在这方面的主要优化包括确保发送和接收日志条目和确认都可以在没有任何线程上下文切换的情况下完成。 VMware vSphere 虚拟机管理程序允许向 TCP 堆栈注册函数,每当收到 TCP 数据时,就会从延迟执行上下文(类似于 Linux 中的 tasklet)调用这些函数
  9. 使用primary和backup共享存储的方式代替各自拥有着自己的存储系统

  10. 让备份虚拟机执行磁盘读取,从而消除磁盘读取数据的记录,。但需要解决backup未读取成功,但primary读取成功的情况

KTurnura commented 7 months ago

其他关于某些定义的说明

不确定性事件

但存在不确定性事件和不确定性操作会影响VM状态

不确定事件和不确定操作影响VM的状态,带来了三个挑战例如:

  1. 正确的捕获所有的输入和不确定事件对于backup 虚拟机确保确定性执行是非常有必要的
  2. 在backup 虚拟机上正确的应用输入和不确定事件
  3. 完成这类任务不降低虚拟机的性能

有时物理硬件也会带到了一些负面影响

该论文中,确定性重放将 VM 的输入以及与写入日志文件的日志条目流中的 VM 执行相关的所有可能的非确定性记录下来。 稍后可以通过从文件中读取日志条目来准确重播VM执行

对于不确定性操作,足够的信息能够保证最终状态的一致性,对于不确定性事件,例如:timer、IO completion interrupt,有精确的指令记录事件在总日志目录中发生的地点

在重放期间,不确定性事件在指令流中的同一点传递。 VMware 确定性重播实现了高效的事件记录和事件传递机制,该机制采用各种技术,包括使用与 AMD [2] 和 Intel [8] 联合开发的硬件性能计数器。

FT primary/backup protocol

我们必须在日志通道上使用严格的FT协议来增加日志条目,来确保我们实现容错,我们的基本要求如下

backup接收primary失败后的任务,并像primary一样,与外部世界进行沟通

Output Requirement 可以通过延迟任何外部数据来保证,直到backupVM 已经能接收所有信息,并允许其重做上次输出节点之间的操作

一个很必要的条件就是必须接受到所有在输出操作之前生成的的所有日志信息,以此允许他执行到最后一个日志条目的位置

假设一次故障立即发生在primary 执行输出操作之后,则backup Vm 需要知道他依然要重做到上次输出操作的时间节点。并且在这个时刻上线(取代primary

给定上述限制,最简单满足Output Requirement的方法就是在每个output操作后创建一个特殊的log 入口(==我理解为该操作也算是一次同步事件==,backup确认他已经接受到了和输出操作相关的日志条目),然后,Output Requirement 可以通过该特定Rule强制执行(在不故障的情况下也需要满足的条件)

主虚拟机可能不会向外部世界发送输出,直到备份虚拟机收到并确认与产生输出的操作相关的日志条目/入口

上图,Primary 的output在接受到Backup的确认后才执行

如果backup VM 已经收到了所有的log entries,包括输出操作的日志,则backup Vm将有能力精确的重做当前输出节点的primary Vm的状态

The Output Rule 外部同步Io实际上可以被缓存,只要在下一次外部通信之前实际将其写入磁盘即可

由于操作系统通过异步中断进行非阻塞网络和磁盘输出以指示完成,因此虚拟机可以轻松地继续执行(不等待backup确认输出,暂停完全等待),并且不一定会立即受到输出延迟的影响。

改进:而在之前的研究中,primary VM必须完全停止

我们不能保证在故障转移情况下所有输出都恰好生成一次。 这里的理解是,Primary可能会在发送output operation 之后崩溃,Backup发送对output的确认并没有被primary接收到,TCP可能会对primary没接收到消息给Backup反馈

检测和回应错误

与logging channel相关的部分

  1. heart beating

    使用UDP

  2. 监控logging channel

backup报错,primary继续运行,停止通过logging channel发送信息

如果primary报错,此时backup会继续运行,此时backup存储区会有一些已经接收并承认但并没有执行的日志,backup VM会先执行这部分日志,backup会停止backup模式(比如不输出程序结果等),像Primary一样与外部进行沟通。

他需要进行 一些特殊的设备声明:告知client自己是新的primary,广播自己的MAC地址,以确保Switch知道新primary的地址,此外,他还需要一些IO问题Section 3.4,同时也需要新启动一个backup VM 存储冗余

日志条目或确认流的停止可能表明虚拟机发生故障。 如果心跳或日志流量停止时间超过特定超时(大约几秒),则声明失败

任何错误检测方法都对脑裂问题敏感,比如因为网络问题backup无法接收到primary的信息,他就会执行take over选项

使用共享存储来存储虚拟机的虚拟磁盘,当primary 或者 backup VM想要 主持,如果检测到有server在运行,则当前VM实际上会停掉他自己想主持的想法

如果VM不能连接到共享存储中,则他们重试该原子操作,直到能访问为止(因为故障可能发生在存储网络上)

容错的实现

启动一个backup虚拟机

创建了一种修改形式的 VMotion,它可以在远程服务器上创建虚拟机的精确运行副本,但不会破坏本地服务器上的虚拟机。

也就是说,我们修改后的 FT VMotion 将虚拟机克隆到远程主机,而不是迁移它。 FT VMotion 还设置日志记录通道,并使源 VM 作为主 VM 进入日志记录模式,并使目标 VM 作为新备份进入重播模式。 与普通 VMotion 一样,FT VMotion 通常会中断主 VM 的执行不到一秒。 因此,在正在运行的虚拟机上启用 FT 是一项简单、无中断的操作。

启动备份虚拟机的另一个方面是选择一个服务器来运行它,由于使用共享存储,且VMware实现了一个集群服务,可以维护管理和资源信息,可以判断那个节点新建最合理

因此该平台导致新建一个冗余可以在分钟内完成

监控Logging Channel

在实现中,管理层对于logging entries for the primary and backup维持了一个大缓存 primary向该缓存中生产log,backup从该缓存中消费

backup会每次发送确认消息给primary:它将一些日志条目从网络读取到日志缓冲区中

这个确认允许VMware FT来确定何时可以发送被Output Rule延迟的输出

如果backup在他需要读下一个日志条目时,遇到了一个空日志缓存,他将等待直到该log entry被缓冲出来

该操作不影响全局性能,担当一个primary遇到一个满的log-buffer,他将停止操作并进行等待,这个执行的停止是一个自然的流控制机制,来降低primary VM 当它以太快的速度生成日志条目时

然而,这个暂停将会影响client,因为此时Primary VM将会完全停止,并且将不在可访问

我们必须设计一个组件来最小化primary buffer 溢出

primary log buffer 溢出的原因 backup 执行速度缓慢,因此消耗log entries 的速度也很缓慢

通常来说,backup 需要和primary 保持相同的执行速率、

然而, 如果托管备份虚拟机的服务器负载过重(因此过度使用资源),则备份虚拟机可能无法获得足够的 CPU 和内存资源来与主虚拟机一样快地执行,尽管备份虚拟机尽了最大努力 备份管理程序的VM调度程序

除了避免长时间的暂停外,还有另外一个我们不希望执行拖延太长的原因

如果Primary VM 失败了,则backup 必须通过重播它在上线并开始与外部世界通信之前已经确认的所有日志条目来赶上,这会显着增加故障转移时间

Operation on FT VMs

比如明确停止(永久)primary,backup也要永久停止,而不是接着自己当primary

比如对primary进行提高CPU核数,backup也同样需要执行

这类操作,特殊控制条目在日志通道上从主服务器发送到备份服务器,以便对备份服务器执行适当的操作。

VMware FT 确保两个虚拟机都不会移动到另一个虚拟机所在的服务器,因为这种情况将不再提供容错能力

唯一可以在主虚拟机和备份虚拟机上独立完成的操作是 VMotion。即主备虚拟机可以独立地VMotion到其他主机

(没太看懂有啥用)

issue for disk io

磁盘操作设置为非阻塞,所以可以并行的执行,同时连接相同磁盘地址的磁盘操会导致不确定性

  1. 我们Disk IO的实现直接使用DMA来进出虚拟机内存,所以链接相同内存页的磁盘操作也会导致不确定性

    我们的解决办法是,通常是用于检测任何此类IO竞争(其实很少见),然后强制这些竞争磁盘的操作在primary 和 backup 上顺序的执行

  2. 磁盘操作也可能在一台VM的一个应用/OS上 磁盘操作和内存访问竞争。因为disk 通过DMA 直接访问一个VM的内存

    例如,如果一个Vm上的一个应用/OS 正在读取内存块,同时,一个磁盘读取该内存块儿,就可能导致不确定的结果。

    这种情况通常不太可能,但我们一定要探测它,并在他发生时解决它

    一种解决方案是在作为磁盘操作目标的页面上临时设置页面保护

    如果 VM 碰巧访问的页面也是未完成的磁盘操作的目标,则页面保护会导致陷阱,并且可以暂停 VM,直到磁盘操作完成

    ==Because 改变MMU 也保护是一个昂贵的操作,我们使用bounce buffer来代替==

    反弹缓冲区是一个临时缓冲区,其大小与磁盘操作访问的内存相同。修改一个磁盘读操作,读取指定数据到bounce buffer, 仅当IO完成时,数据才被复制到客户机内存中

    ==相同的,对于一个磁盘写入操作,将被发送的数据首先被复制到弹性缓冲区内,修改磁盘写入来从弹性缓冲区中写数据。 弹性缓冲区的使用可以有效降低磁盘操作,但我们没有看到任何可见的性能损失==

  3. 当primary发送错误,bakcup接管时,新升级的主虚拟机无法确定磁盘 IO 是否已发送到磁盘或是否成功完成新升级的主虚拟机无法确定磁盘 IO 是否已发送到磁盘或是否成功完成 此外,由于磁盘 IO 不是在备份 VM 上从外部发出的,因此当新升级的主 VM 继续运行时,它们不会有显式 IO 完成,这最终会导致 VM 中的来宾操作系统开始中止或重置 程序

    我们可以发送一个错误完成来指示每个 IO 失败,因为即使 IO 成功完成,返回错误也是可以接受的。 但是,客户端操作系统可能无法很好地响应来自其本地磁盘的错误。相反,我们在备份虚拟机上线过程中重新发出挂起的 IO。 因为我们已经消除了所有竞争,并且所有 IO 直接指定访问哪些内存和磁盘块,所以即使这些磁盘操作已经成功完成,也可以重新发出(即它们是幂等的)

  4. Network issues

    该平台提供了很多VM网络的优化策略,因为底层hypervisor同步更新虚拟机网络设备的状态,但同样这种同步更新操作给VM的状态带来了不确定性,除非我们能够保证所有更新都发生在主设备和备份设备上指令流中的同一点.

    容错网络仿真代码的最大变化是禁用了异步网络优化,使用传入数据包异步更新 VM 环形缓冲区的代码已被修改,以强制guest捕获到虚拟机hypervisor,它可以在其中记录更新,然后将其应用到 VM。

    类似地,通常对于 FT来说,从传输队列异步拉出数据包的代码被禁用,转而通过陷阱完成到虚拟机管理程序的传输(预计如下所述)消除网络设备的异步更新以及第 2.2 节中描述的延迟发送数据包给网络带来了一些性能挑战 我们使用了两种提高VM网络性能(消除网络设备的异步更新以及第 2.2 节中描述的延迟发送数据包给primary网络带来了一些性能挑战)的方法:

    1. 我们实现了集群优化来降低VM traps 和 中断的次数

      1. 当虚拟机以足够的比特率传输数据时,管理程序可以为每组数据 包执行一个传输陷阱,并且在最好的情况下为零陷阱,因为它可以将 数据包作为接收新数据包的一部分进行传输
        1. 对于传入数据包,仅发布一组数据包的中断
    2. 减缓传输数据包带来的延迟

      1. 我们在这方面的主要优化包括确保发送和接收日志条目和确认都可以在没有任何线程上下文切换的情况下完成。 VMware vSphere 虚拟机管理程序允许向 TCP 堆栈注册函数,每当收到 TCP 数据时,就会从延迟执行上下文(类似于 Linux 中的 tasklet)调用这些函数
KTurnura commented 7 months ago

guest是指?

Guest是指让给客人访问电脑系统的帐户

本文中应该是建立在VMM之上的系统

What is hypervisor

虚拟机管理程序是虚拟机系统的一部分; 它与虚拟机监视器 (VMM) 相同。 虚拟机管理程序模拟计算机,并且guest操作系统(和应用程序)在模拟计算机内执行。 Guest运行的模拟通常称为虚拟机。 在本文中,主虚拟机和备份虚拟机是在虚拟机内部运行的Guest,而 FT 是实现每个虚拟机的管理程序的一部分。

KTurnura commented 7 months ago

相关问题FAQ

http://nil.csail.mit.edu/6.824/2022/papers/vm-ft-faq.txt

KTurnura commented 7 months ago

如有其他问题可在issue下咨询