VM-FT

论文引出了什么内容?

很好的论文解读

VM-FT: 确保服务器 高可用 论文中采用了 主备虚拟机,如果备用服务器可以保证和主服务器的状态,那么当主服务器宕机的时候,备用服务器可以立刻接管流量将角色切换为主虚拟机,备用虚拟机必须做到同主虚拟机宕机时的状态一致,不能丢失请求,不能丢失内容, 这也就引出了一些列问题:

  1. 备用服务器如何保证和主服务器的状态一致(这里的状态一致指的是什么?)
  2. 我们有什么方法保证状态一致?
  3. 备用服务器和主服务器之间的通信靠什么?
  4. 备用服务器和主服务器的磁盘空间是共享还是各自存储?(如果)

一些概念:

状态

中断处理

磁盘共享

光纤通道 在 #73 中做了简单的阐述

阻塞/非阻塞

日志通道

顺序

协议

全状态复制:

如果两台机器的CPU状态一致, 内存状态一致, I/O设备状态一致 那么两台机器就同步, 这种方法在论文中被称为 状态转移


我很困惑的是,如果这种方法可以实现,究竟是怎么实现的呢? CPU的寄存器如何全部转移给另一台机器?内存呢? 如果一个运行中的程序,我觉得它的寄存器的变化是飞速的,我们需要什么样的同步能使不阻碍主机运行,并且让备用服务器接收指令并改变状态?内存的变化也是频繁的啊! 所以我觉得这里有点超乎我的想象了

可能的解决方案:

  1. 主备机同步执行每条指令
  2. 要求两台机器硬件一致、时钟同步。
  3. 每条指令执行后,主机和备机的寄存器、内存状态都必须一致。如果不一致,系统会触发容错机制。
(如果两个机器都启动了这个进程) 如果两台机器同时运行同一个进程他们的寄存器状态本身是就同步吗?如果不是,有将会造成什么影响?
(答案是:否)

不确定性事件的影响:

中断时机的不同:

中断是异步事件(外部内部事件触发,而不是程序跳转),中断时机的不同,导致了某个正在运行的线程会被打断,如果中断处理涉及数据写入(如网络包处理),那么内存状态也会不同

主机在第 100 条指令时收到网络包中断 备机在第 102 条指令时收到同样的中断 -> 主机线程 A 被打断 | 备用机线程 B 被打断 -> 网络包由线程 A 处理| 网络包由线程 B 处理 ->写入内存位置 X | 写入内存位置 Y ->寄存器状态变化 路径 A | 路径 B

同理: 网络包到达的顺序: 磁盘读写完成: 用户输入(键盘、鼠标):

这些事件是不可预测的!

复制状态机:

如何将不确定的状态变得确定?

$S_{\text{初始}} + I_{\text{序列}} \Rightarrow S_{\text{最终}}$

主从机器之间通过日志通道进行通信, 主机进行的操作将会按照顺序输出到日志通道中,从机将从通道中取出指令执行,这样相同的 起始状态 + 相同的输入 = 相同的输出(也就保证了相同的状态!) 明确这里的相同输入指的是什么?

复制状态机(RSM)中的 “操作”(Operation),指的是业务逻辑层面的、高层次的、确定性的指令,而不是 CPU 寄存器层面的机器指令。

示例:

假设并且要求这些操作的执行是确定性的。这意味着,如果副本 A 和副本 B 从相同的业务状态开始,都执行了相同的操作 Transfer(A, B, 100),那么它们必然得到相同的最终状态。

这种不确定性究竟是怎么协调的?(共识协议), 这个没有阅读到


困惑解答:

日志通道 (Log Channel): 一条高带宽、低延迟的通道,用于传输:1. Leader 遇到的非确定性事件日志 (中断、I/O 结果)。 2. 备用机的确认信息。 共享存储 (Shared Storage): 通常通过 光纤通道 (Fiber Channel) 或 iSCSI 等实现,主备机都连接到同一份虚拟磁盘文件(如 VMDK)。

中断时机协调: 指令计数同步:Leader 记录中断发生在第 N 条指令之后,并将 $N$ 和中断结果发送给 Follower。Follower 在执行到第 $N$ 条指令之前,强制阻塞等待 Leader 的结果,然后使用 Leader 的结果继续执行。

确定性重放:

Leader 虚拟机 正常运行,并记录所有非确定性事件的发生点和结果。 Follower 虚拟机 紧跟 Leader 运行,执行相同的机器指令流。 当 Leader 遇到一个非确定性事件(如中断、时钟读取)时,它将该事件的类型、发生时机(指令计数)和结果数据通过日志通道发送给 Follower。 当 Follower 运行到 Leader 记录的同一指令计数时,它会阻塞并跳过本地的非确定性事件,而是使用 Leader 提供的确定性结果来更新自己的状态。

只有在 I/O 操作(例如,网络包写入内存)时,Leader 才会将写入的数据通过日志通道发送给 Follower,确保它们写入相同的内容。

有必要对内存要求写入到相同的位置吗? 所谓的相同的位置指的是什么? 两台不同的机器怎么会有相同的位置?

首先,这里的**“相同的位置”指的不是物理机器的内存地址,而是虚拟内存地址** 物理地址不同是可以的

示例:

主机 (Primary) 上的虚拟机执行一条指令,写入 虚拟地址 0x4000。 主机 VM Monitor (VMM/Hypervisor) 将 0x4000 映射到 Host 的 物理地址 0x100000。 备机 (Secondary) 上的虚拟机执行相同的指令,写入 虚拟地址 0x4000。 备机 VMM 将 0x4000 映射到备机的 Host 物理地址 0x500000(注意:这个物理地址和主机不同)。

为什么要保证虚拟地址的相同?

一个程序可能有一个数据结构指针指向 0x100000。如果主机上这个地址存储的是用户数据 $A$,而备机上这个地址存储的是程序代码 $B$,那么当程序试图访问它时,两台机器的执行结果会立即分叉,导致备机无法接管主机。任何内存访问指令(如 Load、Store)的操作数都是虚拟地址。如果同一条指令在主备机上访问了不同的虚拟地址,即使是执行了相同的机器指令流,它们对内存状态的修改也会不同。

究竟是为什么? 虚拟地址不同和相同 最终不也都分配到了不同的地址空间吗 ?

在 VM-FT 场景下,虚拟机(Guest)之所以不能完全自己控制 VA,是因为 Hypervisor 必须介入,并强制其采用确定的、与主机关联的 VA 布局,以服务于“确定性重放”的容错目标

VA 必须同步,是 VM-FT Hypervisor 强制执行的一个约定。它接管了虚拟机的内存管理,确保主备机上虚拟机的内存分配器和加载器看到一个完全相同、且确定性的虚拟内存环境,从而消除了它们在执行相同程序时的内存布局差异。