对于 VM 的内存状态的迁移,XEN 和 KVM 都采用了主流的的预拷贝(pre-copy)的策略。迁移开始之后,源主机 VM 仍在运行,目的主机 VM 尚未启动。迁移通过一个循环,将源主机 VM 的内存数据发送至目的主机 VM。循环第一轮发送所有内存页数据,接下来的每一轮循环发送上一轮预拷贝过程中被 VM 写过的脏页内存 dirty pages。直到时机成熟,预拷贝循环结束,进入停机拷贝阶段,源主机被挂起,不再有内存更新。最后一轮循环中的脏页被传输至目的主机 VM。预拷贝机制极大的减少了停机拷贝阶段需要传输的内存数据量,从而将停机时间大大缩小。

然而,对于更新速度非常快的内存部分,每次循环过程都会变脏,需要重复 pre-copy,同时也导致循环次数非常多,迁移的时间变长。针对这种情况,KVM 虚拟机建立了三个原则:集中原则,一个循环内的 dirty pages 小于等于 50;不扩散原则, 一个循环内传输的 dirty pages 少于新产生的;有限循环原则,循环次数必须少于 30。在实现上,就是采取了以下措施:

  • 有限循环:循环次数和效果受到控制,对每轮 pre-copy 的效果进行计算,若 pre-copy 对于减少不一致内存数量的效果不显著,或者循环次数超过了上限,循环将中止,进入停机拷贝阶段。
  • 在被迁移 VM 的内核设置一个内存访问的监控模块。在内存 pre-copy 过程中,VM 的一个进程在一个被调度运行的期间,被限制最多执行 40 次内存写操作。这个措施直接限制了 pre-copy 过程中内存变脏的速度,其代价是对 VM 上的进程运行进行了一定的限制。

KVM 的预拷贝在线迁移过程详解:

图 1. 源服务器和目标服务器简图
图 2. 内存镜像复制示意图
图 3. 进行有变化的内存复制
图 4. 所需复制的数据在减少
图 5. 状态信息的复制
图 6. 停止源服务器,启动目标服务器