virt-report虚拟化社区动态

热迁移:内存复制、状态交接与业务恢复

本文由 OpenAI Codex (GPT-6-Astra) 辅助编写。

一、热迁移的状态范围与连续性要求

热迁移把客户机的执行从源端交给目的端,用于宿主维护与资源调度。目标是保持内存、CPU 和设备状态对应同一个执行点,并把业务不可服务的时间控制在可接受范围。迁移耗时、客户机停机时间和恢复后的业务延迟需要分别衡量。

其基础是保存与恢复:暂停源端,把客户机可见的内存内容、寄存器和设备状态交给目的端,让目的端在兼容的虚拟硬件上继续执行。若全部复制都发生在暂停之后,大容量内存会直接拉长停机。预拷贝把大部分内存复制提前到客户机运行期间,再处理期间产生的变化。

源端和目的端各有一个 QEMU 进程,分别持有本机的 RAM 映射与设备对象。源端 KVM 记录客户机执行产生的脏页,源 QEMU 读取和发送状态,目的 QEMU 将其装载到自己的对象中;Libvirt 则在两台宿主机上协调准备、接管和清理。迁移数据跨主机传输,本地对象和进程地址各自保留。

本文从普通预拷贝流程入手:两端采用兼容的机器、CPU 和设备配置,磁盘内容通过共享存储或另行复制保持一致,网络也需要在目的端具备接管条件。状态传输和这些外部资源的准备共同组成完整迁移。

源码版本:QEMU 10.2.0。

二、内存、CPU 与设备的一致性

客户机的一条写盘操作可能已经把请求放入内存中的队列,但设备尚未返回完成。如果只复制 RAM 就在目的端启动,设备不知道哪些请求正在处理;如果只恢复 CPU 寄存器,下一条指令读到的内存又可能来自另一个时刻。迁移需要重建一份可以继续执行的机器状态。

状态迁移所需信息交接时要满足的条件
RAM页面内容及客户机物理地址布局最后一批修改已到达,不能用过期页面覆盖新状态
CPU指令位置、寄存器、控制及中断状态与停机时的内存和设备状态一致
设备寄存器、队列位置、定时器和可迁移的内部状态在途操作得到收尾或被设备协议正确保存
外部资源可访问的磁盘内容、网络和后端连接目的端可接管,源端不能继续修改同一份业务状态

最直接的办法是先停机,再复制这些状态。8 GiB RAM 在有效带宽 1 GiB/s 下,仅内存复制就至少需要约 8 秒。预拷贝把首轮和多轮重传安排在客户机运行期间,只把最后一部分工作放入停机窗口,因此需要脏页跟踪来找出复制后发生的修改。

三、准备、运行中复制与停机交接

预拷贝迁移与外部资源切换
目的端先准备兼容机器和接收通道;源端运行时复制 RAM 并重传脏页,停机后完成剩余内存与 CPU、设备状态交接。存储可用与网络接管由管理层协调。
目的端先准备兼容机器和接收通道;源端运行时复制 RAM 并重传脏页,停机后完成剩余内存与 CPU、设备状态交接。存储可用与网络接管由管理层协调。 打开原图
Mermaid 源码
flowchart TB
  accTitle: 预拷贝迁移与外部资源切换
  accDescr: 目的端准备兼容机器,源端运行时复制内存并重传脏页,源端停机后传递剩余内存及 CPU 和设备状态。目的端加载状态,并在存储和网络接管具备条件后恢复客户机。
  A["目的端:兼容机器与接收通道就绪"] --> B["源端运行:首轮 RAM 复制"]
  B --> C["源端运行:脏页迭代重传"]
  C -->|切换条件满足| D["源端停止:剩余 RAM、CPU 与设备状态"]
  D --> E["目的端:加载完整执行状态"]
  E --> F["目的端恢复客户机<br/>源端保持停止"]
  R["管理层:存储可用、访问权与网络接管"] -.-> A
  R -.-> F
  classDef source fill:#eaf0f6,stroke:#8198ac,color:#263c4c;
  classDef destination fill:#e4f1ec,stroke:#438575,color:#173e34;
  classDef coordination fill:#fff4db,stroke:#b89a55,color:#59491e;
  class B,C,D source;
  class A,E,F destination;
  class R coordination;

1. 运行中复制 RAM

目的端准备好机器并等待状态。源端先传内存,客户机继续运行;脏页跟踪记录复制期间再次修改的页,使其进入后续轮次。迁移流同时标识状态处理器、版本与分段,使接收端把状态交给对应 RAM 或设备处理逻辑。

2. 停止源端并恢复目的端

剩余量满足切换条件后,源端暂停 vCPU,协调设备停止,发送最后的 RAM、CPU 寄存器和设备状态。目的端加载完成并具备存储访问、网络接管条件后恢复执行。管理层必须避免两端同时运行同一台客户机。

这里的暂停还要覆盖能够修改客户机内存的设备和后端。只停止 vCPU,不能保证 DMA 或异步 I/O 已停止写入。各状态处理器通过迁移回调保存自己的内容,目的端再按相同协议恢复;迁移流中的 RAM 分段、设备状态与结束标记负责组织这次交接。

四、一次磁盘请求在迁移前后的衔接

以共享存储上的 virtio-blk 磁盘为例,客户机把写请求放入 RAM 中的队列,源端设备开始处理。预拷贝可能已经复制过这段队列内存,但请求随后完成,又会改变完成记录和中断状态。最终交接必须让这些状态一起反映停机时的进度:

阶段源端目的端
运行中复制继续处理请求,记录 RAM 修改接收页面,尚不执行客户机或重复处理队列
停机收尾停止客户机与相关 I/O 活动,完成最后脏页同步和设备状态保存更新 RAM,装载队列处理位置、寄存器和中断状态
恢复执行保持停止,等待管理层确认与清理在原有磁盘内容上继续处理;驱动依据恢复的队列状态推进

共享存储解决两端访问同一份磁盘内容的问题;设备迁移解决队列、完成状态和后端活动的衔接。具体设备需要按自己的协议收尾或保存在途工作。网络同样需要目的端接管原来的连接环境,不能仅凭 RAM 复制成功判断业务已经恢复。

内存迭代的轮次、位图与带宽计算集中在预拷贝专篇;这里的完整性检查包括四项:最终 RAM、CPU 状态、设备状态和外部资源接管。

五、收敛、并行传输与后拷贝的取舍

遇到的限制方案与作用新增成本
停机复制全部内存耗时过长预拷贝:提前复制,大部分时间维持客户机运行持续跟踪修改,部分页面反复发送
单条传输路径无法利用可用带宽MultiFD:并行处理和传输 RAM 批次更多线程、缓冲与跨通道同步
写脏过快,剩余量长期不下降限制写脏,或切换后拷贝结束源端修改前者影响业务执行;后者引入远程缺页和双端故障依赖

这些方案针对不同瓶颈。传输线程不足时增加并行度可能有效;链路已经饱和时,更多线程未必提高吞吐。写脏率过高则需要降低写脏、提高带宽,或改变切换方式。普通预拷贝在目的端接管前通常还保留可继续运行的源端;后拷贝开始后,不能简单让源端恢复执行来回退。

六、把迁移时间、停机和业务影响分开评价

迁移总时间包含运行中的复制阶段。客户机实际停顿指源端停止执行到目的端恢复执行的间隔;QMP 的 downtime 则由迁移实现计时,本例在源端记录,结束边界还受返回通道等因素影响,并非直接测量目的端恢复执行的时刻。业务不可用时间还可能包含网络收敛、客户端超时和服务恢复。这三种口径应分别记录,具体计时位置见停机时间与统计边界。

首先看剩余内存是否下降,再检查停机阶段的设备保存、传输和加载耗时,最后观察客户机恢复后的尾延迟。预拷贝的关键收益是把大规模复制移出停机窗口;它的主要代价是重复传输和迁移期间的资源竞争。带宽、MultiFD、压缩和后拷贝分别影响传输能力、CPU 消耗与切换方式,应依据实际瓶颈选择。

七、按迁移阶段继续阅读

八、参考资料