所谓热迁移, 就是在用户无感知的情况下, 把虚机由远端迁移到目的端.
一, 原理理解
KVM 的热迁移分为共享存储和非共享存储两种, 其最终目的都是为了将内存和磁盘中的数据转移到目的端. 总共要进行 5 个阶段
源端:
1,set_params 阶段: 此阶段根据热迁命令与参数, 遍历 savevm_handlers 链表, 初始化各个模块的迁移特征参数, 完成后向目的端发送 qemu_put_be_32(f, QEMU_VM_FILE_MAGIC), 由此进入 setup 阶段
2,setup 阶段: 这个阶段会遍历 savevm_handlers, 将所有需要热迁设备的 section_id,idstr,instance_id,version_id 信息传递到目的端, 并调用各个设备的 setup 函数
3,iterate 阶段: 此阶段会反复遍历 savevm_handlers 链表上的所有设备, 调用 iterate 函数进行数据传递, 传输完成后, 调用 vm_stop, 暂停源端, 进入 complete 阶段.
4,complete 阶段: 用来传递最后的脏页与迁移信息的清理.
目的端:
1,load 阶段
接收源端需要迁移的设备列表, 从 savevm_handlers 列表中找到对应设备的处理函数, 并以此初始化 loadvm_handlers 链表. 然后, 根据源端传递来的数据, 从 loadvm_handlers 中拿到对应的 load 函数, 并加载数据.
二, 热迁常用技巧
(1) 三种场景速度差别
目前热迁有三种场景, 千兆场景 (速度大概是 75MB), 万兆场景 (速度大概是 300MB), 属于万兆场景但迁移速度上不来 (约 100MB 左右). 第三种情况可能是由于内存降速引起.
(2) 评估迁移时间
watch -n 1 "virsh domjobinfo uuid"
可以通过上面命令, 看下迁移速度再评估最后中断时间
可以查看 / usr/local/var/log/libvirt/qemu/uuid.log, 里面有个 remaining 值, 这个值就是迁不动的 page 数 (乘以 4 后是 kb). 看这个值就可以看出还剩多少内存没有迁走
三, 内存降速问题
有时母机会出现内存降速问题, 导致系统读取磁盘到内存速度降低. 这时可以在发起迁移前, 使用 taskset 绑定子机的 qemu 主线程到未降速的 numa 上, 能提升迁移速度.
(1) 确认降速的 numa 节点. 有两个方法.
a) 通过母机上 / tmp/test_mem/test_mem.sh 脚本测试当前 numa 空闲可用速度. 结果在 numa0.log,numa1.log,test_mem.log 中.
b) 通过上传 pcm-memory.x 这个脚本, 查看 numa 实时使用的速度, 确认内存变化 (这里要根据子机所在的 numa, 看 numa 的写内存. 因为迁移是把已有的内存置为脏页, 只能读, 不能写. 然后子机需要写内存的时候, 就新申请内存. 所以内存变化主要看写内存速度), 决定中断时长. 这个脚本需要:
echo 0> /proc/sys/kernel/nmi_watchdog 设置系统参数
./pcm-memory.x 执行脚本, 查看实时速度
echo 1> /proc/sys/kernel/nmi_watchdog 用完后恢复系统参数
(2) numactl- - hardware, 查看降速 numa 对应的 cpu.
(3) virsh vcpuinfo uuid, 获取子机的 cpu 分布. 或着 /usr/sbin/tools/cvminfo 也可以看到.
(4) taskset -pc 6-11,18-23 pid, 把子机的 qemu 主线程绑定到另外一个 numa 上. 这里用 vcpu 命令绑核没有作用.
(5) 发起迁移, 就能解决内存降速导致的迁移速度慢问题. 这个操作能提高点迁移速度
来源: http://blog.51cto.com/12814931/2130733