这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

快照

cloud hypervisor 快照

1 - 快速开始

cloud hypervisor 快照快速开始

机器配置

安装好 cloud hypervisor,测试机器为 debian13 物理机器,intel x86-64 cpu。

$ cloud-hypervisor --version
cloud-hypervisor v50.0.0

$ ch-remote --version
ch-remote v50.0.0

$ uname -a
Linux skydev3 6.12.57+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.57-1 (2025-11-05) x86_64 GNU/Linux

内核

为了极致的启动速度和测试效率,推荐使用 Cloud Hypervisor 官方提供的测试资源,或者使用 Alpine Linux 这种极简发行版。

mkdir -p ~/work/test/cloudhypervisor
cd ~/work/test/cloudhypervisor

ch官方内核

linux kernel 采用之前构建的 x86 内核(45MB),方便起见复制到本地:

cp ~/work/code/cloud-hypervisor/linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin .

这个内核版本是 6.12,非常新。

记录文件地址备用:

/home/sky/work/test/cloudhypervisor/vmlinux.bin

rootfs

ubuntu cloud image

兼容性最好,但是有点大:

# 下载 Ubuntu 24.04 (Noble) 云镜像
mkdir ubuntu-cloud-image
cd ubuntu-cloud-image
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img

# Cloud Hypervisor 需要 raw 格式,且需要解压
sudo apt install -y qemu-utils
qemu-img convert -p -f qcow2 -O raw noble-server-cloudimg-amd64.img rootfs.raw

# 调整大小(可选,云镜像默认只有 2GB 左右)
qemu-img resize rootfs.raw 4G

操作之后得到的 rootfs 为:

ls -lh                       
total 2.4G
-rw-rw-r-- 1 sky sky 598M Dec 13 21:20 noble-server-cloudimg-amd64.img
-rw-r--r-- 1 sky sky 4.0G Dec 30 17:07 rootfs.raw

记录文件路径备用:

/home/sky/work/test/cloudhypervisor/ubuntu-cloud-image/rootfs.raw

Alpine Linux

TODO

启动

启动 microvm:

sudo rm -rf /home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock
sudo /home/sky/work/soft/cloudhypervisor/bin/cloud-hypervisor \
    --api-socket /home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock \
    --cpus boot=1 \
    --memory size=4G \
    --kernel /home/sky/work/test/cloudhypervisor/vmlinux.bin \
    --cmdline "root=/dev/vda1 console=hvc0 rw" \
    --disk path=/home/sky/work/test/cloudhypervisor/ubuntu-cloud-image/rootfs.raw

在另外一个终端,先 pause:

sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock pause

再执行快照命令,快照文件输出到 snapshot-4g 文件夹:

mkdir -p snapshot-4g
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  snapshot file:///home/sky/work/test/cloudhypervisor/snapshot-4g

完成后可以看到:

ls -lh ./snapshot-4g

文件列表为:

total 4.1G
-rw------- 1 root root 1.4K Dec 30 17:23 config.json
-rw------- 1 root root 4.0G Dec 30 17:23 memory-ranges
-rw------- 1 root root  42K Dec 30 17:23 state.json

执行关闭命令,关闭这个 microvm

sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  resume
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  shutdown
sleep 1
sudo rm -rf /home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock

快照恢复

sudo /home/sky/work/soft/cloudhypervisor/bin/cloud-hypervisor \
    --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock \
    --restore source_url=file:///home/sky/work/test/cloudhypervisor/snapshot-4g

2 - 快照文件信息

cloud hypervisor 快照文件信息

文件列表

快照生成时,需要指定一个目录,然后会生成如下三个文件,以4G内存的虚拟机为例:

ls -lh
total 4.1G
-rw------- 1 root root 1.4K Dec 30 17:23 config.json
-rw------- 1 root root 4.0G Dec 30 17:23 memory-ranges
-rw------- 1 root root  42K Dec 30 17:23 state.json

config.json

config.json 格式化之后的内容:

{
  "cpus": {
    "boot_vcpus": 1,
    "max_vcpus": 1,
    "topology": null,
    "kvm_hyperv": false,
    "max_phys_bits": 46,
    "affinity": null,
    "features": {
      "amx": false
    },
    "nested": true
  },
  "memory": {
    "size": 4294967296,
    "mergeable": false,
    "hotplug_method": "Acpi",
    "hotplug_size": null,
    "hotplugged_size": null,
    "shared": false,
    "hugepages": false,
    "hugepage_size": null,
    "prefault": false,
    "zones": null,
    "thp": true
  },
  "payload": {
    "firmware": null,
    "kernel": "/home/sky/work/test/cloudhypervisor/vmlinux.bin",
    "cmdline": "root=/dev/vda1 console=hvc0 rw",
    "initramfs": null
  },
  "rate_limit_groups": null,
  "disks": [
    {
      "path": "/home/sky/work/test/cloudhypervisor/ubuntu-cloud-image/rootfs.raw",
      "readonly": false,
      "direct": false,
      "iommu": false,
      "num_queues": 1,
      "queue_size": 128,
      "vhost_user": false,
      "vhost_socket": null,
      "rate_limit_group": null,
      "rate_limiter_config": null,
      "id": "_disk0",
      "disable_io_uring": false,
      "disable_aio": false,
      "pci_segment": 0,
      "serial": null,
      "queue_affinity": null
    }
  ],
  "net": null,
  "rng": {
    "src": "/dev/urandom",
    "iommu": false
  },
  "balloon": null,
  "fs": null,
  "pmem": null,
  "serial": {
    "file": null,
    "mode": "Null",
    "iommu": false,
    "socket": null
  },
  "console": {
    "file": null,
    "mode": "Tty",
    "iommu": false,
    "socket": null
  },
  "debug_console": {
    "file": null,
    "mode": "Off",
    "iobase": 233
  },
  "devices": null,
  "user_devices": null,
  "vdpa": null,
  "vsock": null,
  "pvpanic": false,
  "iommu": false,
  "numa": null,
  "watchdog": false,
  "pci_segments": null,
  "platform": null,
  "tpm": null,
  "landlock_enable": false,
  "landlock_rules": null
}

这个 config.json 文件是 Cloud Hypervisor 在执行快照(Snapshot)时生成的,它记录了虚拟机在快照那一刻的静态配置信息。当恢复(Restore)快照时,Cloud Hypervisor 会读取这个文件来重建虚拟机的“骨架”(CPU、内存大小、磁盘路径等),然后再加载内存和设备状态。

关键配置解读:

CPU 设置 (cpus)

  • boot_vcpus: 1: 虚拟机启动时分配了 1 个 vCPU。
  • max_vcpus: 1: 最大也是 1,说明这台 VM 不支持 CPU 热插拔(如果要支持,max_vcpus 通常要大于 boot_vcpus)。
  • nested: true: 嵌套虚拟化已启用。这意味着您在这个 MicroVM 里面还可以运行 KVM(例如在 VM 里运行 Docker 或 QEMU)。这在测试环境中很有用。

内存设置 (memory)

  • size: 4294967296: 即 4GB (4 * 1024 * 1024 * 1024)。
  • hotplug_method: “Acpi”: 如果支持内存热插拔,将使用 ACPI 机制通知 Guest OS。
  • thp: true: 启用了 Transparent Huge Pages(透明大页),这通常有助于减少 TLB miss,提升内存访问性能。

启动载荷 (payload)

这是 Direct Kernel Boot 的核心配置。

  • kernel: /home/sky/work/test/cloudhypervisor/vmlinux.bin

    注意:这里记录的是绝对路径。如果把快照目录复制到另一台机器上去恢复,必须确保那台机器的相同路径下也有这个内核文件,否则恢复会失败。

  • cmdline: root=/dev/vda1 console=hvc0 rw

    • root=/dev/vda1: 指定根文件系统挂载点。
    • console=hvc0: 关键点。Cloud Hypervisor 默认使用 Virtio Console (hvc0) 而不是传统的串口 (ttyS0)。如果您在启动时看不到输出,需要检查 Guest OS 是否启用了 hvc0 的 getty 服务。

磁盘设备 (disks)

  • path: /home/sky/work/test/cloudhypervisor/ubuntu-cloud-image/rootfs.raw

    同样是绝对路径。恢复快照时,程序会去这个位置找磁盘文件。如果磁盘文件被删了或者移动了,恢复会报错。

  • readonly: false: 磁盘是可读写的。

  • direct: false: 没有开启 Direct I/O(O_DIRECT),意味着磁盘读写会经过宿主机的 Page Cache。

网络 (net)

  • null: 您启动这个虚拟机时没有配置网络接口。它是一个“单机”环境,无法联网。

控制台与串口 (console & serial)

  • console (Virtio Console):
    • mode: “Tty”。这意味着虚拟机的 hvc0 输出被重定向到了宿主机运行 cloud-hypervisor 进程的当前终端(TTY)。
  • serial (Legacy Serial):
    • mode: “Null”。传统的串口(ttyS0)被禁用了/未连接。这就是为什么上面的 cmdline 必须用 console=hvc0 的原因。

随机数生成器 (rng)

  • src: “/dev/urandom”:

    虚拟机配置了 Virtio RNG 设备,透传宿主机的 /dev/urandom。这对于 MicroVM 来说很重要,可以加速虚拟机启动(避免因为熵不足导致启动阻塞)。

注意事项:

  1. 路径依赖风险:这个 config.json 文件对宿主机的文件路径(Kernel 和 Disk)有强依赖。如果在本地测试备份/恢复没问题。如果要在不同机器间迁移快照,需要在恢复前修改这个 json 文件里的路径,或者确保两台机器目录结构一致。

  2. 嵌套虚拟化:

    默认开启了 nested: true,这会增加一些 CPU 开销,如果不需要在 VM 里跑 VM,建议启动时去掉相关参数以提升性能。

    关闭的方法:在启动时配置 cpu为 nested off,例如 --cpus boot=1,nested=off \

state.json

state.json 文件大小约为 42 KB。

在 Cloud Hypervisor 的快照体系中,state.json 与 config.json 扮演着完全不同但互补的角色。

如果说 config.json 是虚拟机的**“骨架”(硬件配置),那么 state.json 就是虚拟机的“灵魂”**(运行时的瞬间状态)。

存放的信息

文件记录了虚拟机在暂停那一瞬间,所有“非静态”的、动态变化的数据。具体包括:

  • vCPU 寄存器状态:这是最核心的部分。包含:
    • 通用寄存器:RAX, RBX, RSP (栈指针), RIP (指令指针 - 代码执行到哪一行了)。
    • 控制寄存器:CR0, CR3 (页表地址), CR4 等。
    • 段寄存器:CS, DS, SS 等。
    • 浮点数与向量寄存器:用于数学计算的状态。
    • 简单说:它记录了 CPU 下一条指令要算什么,以及当前的计算结果存在哪。
  • 设备后端状态 (Virtio Devices):
    • Virtio Queues (虚拟队列):记录了磁盘或网卡读写到哪一个位置了(Available Ring 和 Used Ring 的索引)。
    • Feature Bits:宿主机和虚拟机协商好了开启哪些功能(比如是否开启了巨型帧、多队列等)。
  • 中断控制器状态 (vPIC / vIOAPIC / LAPIC):
    • 记录当前有哪些中断正在排队等待 CPU 处理,哪些中断被屏蔽了。
  • 时钟与计时器:
    • 虚拟机内部的时间偏移量,确保恢复后时间能尽量同步。

用处

它的唯一作用就是“现场还原”。

当执行 resume 或从文件恢复虚拟机时:

  1. Cloud Hypervisor 先读取 config.json 创建出 CPU 线程和设备对象(造出机器)。
  2. 然后读取 memory 文件把 RAM 数据填回去(恢复记忆)。
  3. 最后读取 state.json,把每一个 CPU 寄存器的值填回去,把网卡/磁盘队列的指针拨回到原来的位置(恢复思维)。

如果没有 state.json,虚拟机虽然有内存数据,但 CPU 不知道该从内存的哪个地址开始执行指令,也不知道刚才磁盘读写到一半的数据该怎么处理,虚拟机就会立刻崩溃。

注意事项

  1. 绝对不要手动修改

    config.json 里的磁盘路径可以手动改(比如迁移机器后路径变了),但 state.json 里的数据是极度敏感的二进制状态的序列化。

    • 风险:改错一个标点或数字,CPU 恢复时的寄存器状态就会错乱,导致 Guest OS 报 Kernel Panic 或直接死机。
    • 建议:视其为只读的二进制文件。
  2. 版本强耦合 (Version Lock)

    Cloud Hypervisor 开发迭代很快,state.json 的内部结构(Schema)经常会变。

    • 风险:用 v50.0.0 生成的 state.json,很大可能无法在 v51.0.0 或 v52.0.0 上恢复。
    • 建议:生产环境中,快照恢复必须使用与创建快照时完全相同版本的 Cloud Hypervisor。
  3. 与内存文件的原子性

    state.json 和同目录下的内存文件(通常叫 memory)是即时对应的。

    在 Cloud Hypervisor 的快照体系中,state(或者您看到的 state.json)与 config.json 扮演着完全不同但互补的角色。

    如果说 config.json 是虚拟机的**“骨架”(硬件配置),那么 state.json 就是虚拟机的“灵魂”**(运行时的瞬间状态)。

  4. 包含敏感数据

    • 风险:由于它保存了 CPU 寄存器,如果快照时某个程序正在处理密码或私钥,这些明文密钥可能正躺在 state.json 的寄存器值里。
    • 建议:如果是在公有云或不可信环境传输快照,必须像保护磁盘文件一样保护 state.json。
  5. CPU 拓扑一致性

    state.json 里的 vCPU 数据列表是按照 config.json 里的 CPU 数量顺序排列的。恢复时,宿主机不仅要提供相同数量的 CPU,最好连 CPU 的型号特性(Host CPU Model)也尽量保持一致,否则可能出现指令集不兼容(比如快照时用到了 AVX512,恢复的机器不支持)。

memory-ranges

以 4g 内存规格的快照文件为例:

$ ls -lh
total 4.1G
-rw------- 1 root root 1.4K Dec 30 19:13 config.json
-rw------- 1 root root 4.0G Dec 30 19:13 memory-ranges
-rw------- 1 root root  35K Dec 30 19:13 state.json

可以使用支持稀疏文件的 tar -S 命令来将这个稀疏文件打包并使用 zstd 压缩:

sudo tar -cvSf snapshot.tar.zstd -I 'zstd -T0' config.json memory-ranges state.json

打包出来的 snapshot.tar.zstd 文件只有区区 67M,非常的小:

ls -lh
total 4.1G
-rw------- 1 root root 1.4K Dec 30 19:13 config.json
-rw------- 1 root root 4.0G Dec 30 19:13 memory-ranges
-rw-rw-r-- 1 sky  sky   67M Jan  4 15:39 snapshot.tar.zstd
-rw------- 1 root root  35K Dec 30 19:13 state.json

复制这个文件到其他目录,然后以支持稀疏文件的 tar 命令进行解压缩:

mkdir snapshot-4g-distributed
cd snapshot-4g-distributed
cp ../snapshot-4g/snapshot.tar.zstd .

sudo tar -xvSf snapshot.tar.zstd -I 'zstd -d'

解压缩之后的目录文件为:

ls -lh 
total 4.1G
-rw------- 1 root root 1.4K Dec 30 19:13 config.json
-rw------- 1 root root 4.0G Dec 30 19:13 memory-ranges
-rw-rw-r-- 1 sky  sky   67M Jan  4 15:44 snapshot.tar.zstd
-rw------- 1 root root  35K Dec 30 19:13 state.json

memory-ranges 文件解压缩之后恢复到 4.0G 的表面大小。为了验证这个 memory-ranges 文件依然是稀疏文件,我们再次用 tar 命令进行打包压缩测试:

sudo tar -cvSf snapshot2.tar.zstd -I 'zstd -T0' config.json memory-ranges state.json

重新打包的 snapshot2.tar.zstd 文件依然是 67M,验证前面对稀疏文件的打包/传输/解包过程都是支持稀疏文件的。

ls -lh                                                                              
total 4.2G
-rw------- 1 root root 1.4K Dec 30 19:13 config.json
-rw------- 1 root root 4.0G Dec 30 19:13 memory-ranges
-rw-r--r-- 1 root root  67M Jan  4 15:48 snapshot2.tar.zstd
-rw-rw-r-- 1 sky  sky   67M Jan  4 15:44 snapshot.tar.zstd
-rw------- 1 root root  35K Dec 30 19:13 state.json

因此,对于快照文件的存储和传输,使用支持稀疏文件的打包压缩方式是必须的,可以极大的减少存储和网络传输的流量压力,以及下载快照文件带来的延迟。

重复这个测试,对其他内存规格的快照文件进行打包和压缩:

3 - 优化性能

cloud hypervisor 快照优化性能

准备工作

准备目录和文件

继续使用之前的 work/test/cloudhypervisor 目录:

cd /home/sky/work/test/cloudhypervisor

启动

冷启动虚拟机,用于制作快照,注意修改内容大小设置:

sudo /home/sky/work/soft/cloudhypervisor/bin/cloud-hypervisor \
    --api-socket /home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock \
    --cpus boot=1,nested=off \
    --memory size=512M \
    --kernel /home/sky/work/test/cloudhypervisor/vmlinux.bin \
    --cmdline "root=/dev/vda1 rw quiet 8250.nr_uarts=0" \
    --disk path=/home/sky/work/test/cloudhypervisor/ubuntu-cloud-image/rootfs.raw \
    --console off \
    --serial off \
    --log-file /dev/null

制作快照

根据前面设置的内存大小,制作快照,保存在不同的目录下,备用:

rm -rf /home/sky/work/test/cloudhypervisor/snapshot-4g
mkdir -p /home/sky/work/test/cloudhypervisor/snapshot-4g
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock pause
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  snapshot file:///home/sky/work/test/cloudhypervisor/snapshot-4g
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  resume
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  shutdown
sudo fuser -k -TERM /home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock

重复以上操作,可以分别制作出 512M/1G/2G/4G 的快照文件,用于后面的恢复操作。

恢复虚拟机

执行恢复虚拟机的命令,注意选择快照文件的来源目录,其实就是选择不同的内存规格:

sudo /home/sky/work/soft/cloudhypervisor/bin/cloud-hypervisor \
    --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock \
    --restore source_url=file:///home/sky/work/test/cloudhypervisor/snapshot-4g

恢复之后,虚拟机是处于 pause 状态的,因此还要执行 resume 才能唤醒到正常运行状态:

sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  resume

恢复性能测试

默认

使用脚本 test_restore_speed.sh 进行测试,执行前修改脚本中的这一行,指定要使用的不同内存规格的快照文件:

SNAPSHOT_URL="file:///home/sky/work/test/cloudhypervisor/snapshot-512m"

执行前强制清理 page cache:

./test_restore_speed.sh false

多次测试的结果汇总为:

====== 开始性能测试 (Cache: false Size=4G) ======

 1. Load (Disk -> RAM)     :   1913.322 ms
 2. Resume (CPU Active)    :     16.584 ms
 --------------------------------------------------
 3. Total Recovery         :   1929.907 ms

====== 开始性能测试 (Cache: false Size=2G) ======

 1. Load (Disk -> RAM)     :    985.878 ms
 2. Resume (CPU Active)    :     14.172 ms
 --------------------------------------------------
 3. Total Recovery         :   1000.050 ms

====== 开始性能测试 (Cache: false Size=1G) ======

 1. Load (Disk -> RAM)     :    533.121 ms
 2. Resume (CPU Active)    :     15.142 ms
 --------------------------------------------------
 3. Total Recovery         :    548.263 ms

====== 开始性能测试 (Cache: false Size=512M) ======

 1. Load (Disk -> RAM)     :    304.199 ms
 2. Resume (CPU Active)    :     15.110 ms
 --------------------------------------------------
 3. Total Recovery         :    319.310 ms

page cache优化

类似的,不过执行前执行 page cache 优化:

./test_restore_speed.sh true
====== 开始性能测试 (Cache: true Size=4G) ======

 1. Load (Disk -> RAM)     :    623.998 ms
 2. Resume (CPU Active)    :     14.062 ms
 --------------------------------------------------
 3. Total Recovery         :    638.060 ms

====== 开始性能测试 (Cache: true Size=2G) ======

 1. Load (Disk -> RAM)     :    333.440 ms
 2. Resume (CPU Active)    :     17.197 ms
 --------------------------------------------------
 3. Total Recovery         :    350.637 ms

====== 开始性能测试 (Cache: true Size=1G) ======

 1. Load (Disk -> RAM)     :    190.534 ms
 2. Resume (CPU Active)    :     16.542 ms
 --------------------------------------------------
 3. Total Recovery         :    207.076 ms

====== 开始性能测试 (Cache: true Size=512M ======

 1. Load (Disk -> RAM)     :    105.908 ms
 2. Resume (CPU Active)    :     16.547 ms
 --------------------------------------------------
 3. Total Recovery         :    122.456 ms

HugePages 优化

类似,但是在启动虚拟机时设置内存为 hugepages=on:

sudo /home/sky/work/soft/cloudhypervisor/bin/cloud-hypervisor \
    --api-socket /home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock \
    --cpus boot=1,nested=off \
    --memory size=1G,hugepages=on \
    --kernel /home/sky/work/test/cloudhypervisor/vmlinux.bin \
    --cmdline "root=/dev/vda1 rw quiet 8250.nr_uarts=0" \
    --disk path=/home/sky/work/test/cloudhypervisor/ubuntu-cloud-image/rootfs.raw \
    --console off \
    --serial off \
    --log-file /dev/null

同样制作快照,为了和之前 hugepages=off 的快照区分,存放在不同的目录,以后缀 -hugepage 为标志:

rm -rf /home/sky/work/test/cloudhypervisor/snapshot-1g-hugepage
mkdir -p /home/sky/work/test/cloudhypervisor/snapshot-1g-hugepage
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock pause
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  snapshot file:///home/sky/work/test/cloudhypervisor/snapshot-1g-hugepage
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  resume
sudo /home/sky/work/soft/cloudhypervisor/bin/ch-remote --api-socket=/home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock  shutdown
sudo fuser -k -TERM /home/sky/work/test/cloudhypervisor/cloud-hypervisor.sock

继续测试,开启 hugepage + 不开启 page cache 基本没差别:

====== 开始性能测试 (Cache: false Size=4G) ======

 1. Load (Disk -> RAM)     :   1906.534 ms
 2. Resume (CPU Active)    :     15.309 ms
 --------------------------------------------------
 3. Total Recovery         :   1921.843 ms

====== 开始性能测试 (Cache: false Size=2G) ======

 1. Load (Disk -> RAM)     :    985.883 ms
 2. Resume (CPU Active)    :     13.876 ms
 --------------------------------------------------
 3. Total Recovery         :    999.759 ms

====== 开始性能测试 (Cache: false Size=1G) ======

 1. Load (Disk -> RAM)     :    521.281 ms
 2. Resume (CPU Active)    :     14.697 ms
 --------------------------------------------------
 3. Total Recovery         :    535.978 ms

====== 开始性能测试 (Cache: false Size=512M) ======

 1. Load (Disk -> RAM)     :    300.310 ms
 2. Resume (CPU Active)    :     15.617 ms
 --------------------------------------------------
 3. Total Recovery         :    315.927 ms

开启 hugepage + 开启 page cache 能快一点:

====== 开始性能测试 (Cache: true Size=4G) ======

 1. Load (Disk -> RAM)     :    526.327 ms
 2. Resume (CPU Active)    :     15.826 ms
 --------------------------------------------------
 3. Total Recovery         :    542.153 ms

====== 开始性能测试 (Cache: true Size=2G) ======

 1. Load (Disk -> RAM)     :    312.838 ms
 2. Resume (CPU Active)    :     15.331 ms
 --------------------------------------------------
 3. Total Recovery         :    328.169 ms

====== 开始性能测试 (Cache: true Size=1G) ======

 1. Load (Disk -> RAM)     :    153.869 ms
 2. Resume (CPU Active)    :     16.558 ms
 --------------------------------------------------
 3. Total Recovery         :    170.427 ms

====== 开始性能测试 (Cache: true Size=512M ======

 1. Load (Disk -> RAM)     :    102.818 ms
 2. Resume (CPU Active)    :     15.310 ms
 --------------------------------------------------
 3. Total Recovery         :    118.128 ms

性能对比分析

将上面测试的几组数据汇总,对比一下:

内存规格 操作 默认(强制清理page cache) 开启 page cache 不开启 page cache + 开启 hugepage 开启 page cache + 开启 hugepage
4G restore 1913.322 ms 623.998 ms 1906.534 ms 526.327 ms
resume 16.584 ms 14.062 ms 15.309 ms 15.826 ms
total 1929.907 ms 638.060 ms 1921.843 ms 542.153 ms
2G restore 985.878 ms 333.440 ms 985.883 ms 312.838 ms
resume 14.172 ms 17.197 ms 13.876 ms 15.331 ms
total 1000.050 ms 350.637 ms 999.759 ms 328.169 ms
1G restore 533.121 ms 190.534 ms 521.281 ms 153.869 ms
resume 15.142 ms 16.542 ms 14.697 ms 16.558 ms
total 548.263 ms 207.076 ms 535.978 ms 170.427 ms
512M restore 304.199 ms 105.908 ms 300.310 ms 102.818 ms
resume 15.110 ms 16.547 ms 15.617 ms 15.310 ms
total 319.310 ms 122.456 ms 315.927 ms 118.128 ms

分析:

  1. resume 操作的时间非常固定,稳定在 15 毫秒左右,不受内存规格和各种优化策略的影响
  2. restore 操作和内存规格影响非常大,基本呈现线性
  3. 开启 page cache 能极大的加速 restore 的速度,但也只能加速到 30% 左右,不能直接到非常小,而且也是和内存规格直接相关(几乎也是线性)
  4. 开启 hugepage 能再次加速 restore 的速度,但很有限。

结论:

  1. restore 操作的确是在读取和操作完整的内存快照文件,并没有跳过空闲内存

4 - 延迟加载

cloud hypervisor 实现延迟加载的快照方式