Skip to content

迁移与快照:状态持久化链路

概述

在 CubeSandbox 的数据面里,快照能力直接决定了冷启动体验。其本质是把 VM 运行时状态拆解成可持久化的多个子快照,并在恢复时按依赖关系重建。

一句话总结:

快照不是“存一份内存”,而是“保存一个可恢复的系统状态图”。

代码定位

目录/文件作用
vmm/src/vm.rssnapshot() / restore() 主入口
vmm/src/migration.rs迁移与快照协调逻辑
vmm/src/memory_manager.rs内存状态导出与恢复
vmm/src/device_manager.rs设备状态导出与恢复
vmm/src/cpu.rsvCPU 上下文保存与恢复
vm-migration/通用迁移数据结构与协议抽象

快照状态模型

建议把状态分三层理解:

  1. 配置态(可重建):CPU 数、内存布局、设备拓扑
  2. 运行态(必须保存):寄存器、队列游标、内存页内容
  3. 兼容态(用于校验):版本号、feature mask、schema 版本
状态类别是否必须持久化说明
VM 配置恢复时用于构造骨架
vCPU 寄存器决定恢复后执行位置
Guest 内存应用与内核现场
设备内部状态请求队列与设备行为一致性
临时统计计数器可在恢复后重建

创建快照流程

关键约束:

  • 快照窗口内必须冻结可变状态
  • 子系统快照顺序要固定,确保可重复恢复
  • 失败要可回滚(至少不破坏运行中的 VM)

恢复流程与依赖顺序

恢复顺序通常是:配置骨架 -> 内存 -> 设备 -> vCPU -> 运行

为什么 vCPU 最后恢复?

  • 因为一旦 vCPU 开跑,就会读写内存并触发设备交互
  • 只有在内存和设备都就绪后恢复 vCPU,才能保证一致性

兼容性与演进策略

快照格式不可避免会演进。建议采用:

  1. schema_version 强制字段
  2. 关键 capability bitmap(CPU/设备)
  3. 向后兼容读取 + 向前拒绝策略
场景建议策略
小版本升级保持向后兼容读取
大版本升级显式转换或阻断恢复
feature 不匹配启动时预检并给出可读错误

性能优化点

1) 内存快照优化

  • 优先使用 mmap/文件映射,减少复制
  • 支持脏页跟踪时,增量快照优先

2) 设备快照优化

  • 只保存恢复必需状态
  • 避免保存可从配置重建的冗余信息

3) 并行恢复

  • 在依赖允许的前提下并行恢复多个设备
  • 控制恢复并行度,避免启动瞬时抖动

常见故障与排查

1) 恢复后 VM 立即崩溃

  • 检查 CPU 上下文是否完整恢复
  • 检查内存映射地址与原快照是否一致
  • 检查设备 feature 协商是否兼容

2) 恢复后设备不可用

  • 检查设备 snapshot 数据是否缺字段
  • 检查队列状态(avail/used 索引)
  • 检查中断注册是否在恢复后重新绑定

3) 恢复耗时波动大

  • 检查 snapshot 体积与存储介质吞吐
  • 检查是否发生大量小文件随机 IO
  • 检查恢复阶段是否串行化过多

落地检查清单(Runbook)

  • [ ] 快照前已暂停 vCPU 与设备
  • [ ] 快照包含 config/cpu/memory/device/meta 五类状态
  • [ ] 恢复顺序固定且有失败回滚路径
  • [ ] 版本与 capability 做了预检
  • [ ] 恢复完成后有健康探测(应用层 + 系统层)

小结

快照/恢复的难点不在“保存”,而在“一致恢复”。只要把握住冻结窗口、依赖顺序、版本兼容三件事,就能把这条链路做到稳定且可运维。