QEMU FT方案

背景

因为对qemu的fault tolerance技术颇有兴趣,在查询资料时找到了一个IBM实现的MicroCheckpointing方案实现的ft查看文档并整理了一下这个ft方案的原理

MicroCheckpointing

基本概念 Micro-Checkpoints (MC) 默认工作在QEMU虚拟机热迁移的逻辑上,可以被简单的理解为“在执行不会结束的热迁移”。比如,在一个确定的周期譬如0.01s去的循环里去执行如下逻辑:

1
2
3
4
5
1. 在N ms之后stop vm(paused)
2. 通过调用live migration的逻辑生成一个MC用于标识dirty memory并写入到qemu本地的暂存区
3. Resuse vm
4. 传输MC到目标节点
5. 重复1

当发生failure的情况,目标节点的机器用最新的MC恢复guest

这里涉及的几个问题

MC本身的设备I/O一致性

对qemu guest来说,设备I/O的一致性主要包括网络设备和存储设备

即在这N ms后vm stop,这段时间里,内部往外的网络包都会被cache住,直到MC被传输结束

存储设备则需要保证MC传输结束这段时间磁盘内容也被同步了,如果本来使用的就是共享磁盘则问题不大,同理也是需要磁盘I/O在MC之间也是被cache住的

这里有一点比较奇怪,就是既然vm已经处于stop状态,为什么还需要阻止网络包往外发(实际上应该没有网络包了)不过可以理解的是,这个目的是出于failure后恢复的考虑,这样恢复到目标节点之后,这些网络包都会被回复掉,保证MC的一致性

出于这些一致性考虑,MC的步骤需要作出如更改:

1
2
3
4
5
6
7
8
9
10
11
1. Insert a new Qdisc plug (Buffer A).
2. 在N ms之后stop vm(paused)
3. 通过调用live migration的逻辑生成一个MC用于标识dirty memory并写入到qemu本地的暂存区
4. Insert a *new* Qdisc plug (Buffer B). This buffers all new packets only.
5. 立刻回复VM并继续往下运行保持继续工作 (making use of Buffer B).
6. 传输MC到目标节点
7. 等到传输结果被确认
8. 确认传输成功
9. Release the Qdisc plug for Buffer A.
10. Qdisc Buffer B now becomes (symbolically rename) the most recent Buffer A
11. 继续步骤2

根据以上步骤,我们可以知道一个recent Buffer里面会buffer的数据包是上一次MC创建的时候VM resume开始到下一个MC传输完成的数据包,这个逻辑为什么能够保证网络一致呢

举一个具体的例子 比如当前VM在Buffer A里面保存的数据包P1,然后第一次执行MC得到了MC1,然后VM继续运行,创建了Buffer B来拦截新的数据包,到MC1传输完成之后P1被送出去了,Buffer A被清空,而这段时间里面由Buffer B拦截了P2,这个时候如果发生了Fail,目标的机器会恢复到MC1的状态,而因为Buffer B拦截了P2可知,MC1继续运行会发送P2,因此网络连接可以继续进行

Failure Recovery

基于micro-checkpointing高频率的特性,每秒都会生成多个MC。即使错过了个别MC也没有关系,因为I/O Buffer保证了在下一个MC被传输完成之后才会继续运行。

因此判断出错的有以下两种情况:

  1. MC over TCP/IP: 一旦socket连接断开. 这问题可能出现在传输最后一个MC的时候流量太大或者是确认MC传输成功的请求超时等。

  2. MC over RDMA: 因为无限带宽的逻辑没有提供任何底层的超时机制,这个实现给QEMU的RDMA migration protocol 增加了简单的keep-alive。如果发生了多少次keep-alive消息的丢失则认为发生了fail。

在这两种情况下主备两端都能够通过一样的机制判断对方是不是挂掉了

如果主节点被判断挂掉了,备节点就会使用最近的MC恢复启动

如果备节点被判断挂掉了,就执行和live migrate相同的逻辑重新启动一个备份节点

总结

这个方案是一个很好的利用live migrate实现的ft方案

尤其是里面提到的如何保证网络一致,以及通过Qdisc保证网络包顺序,这个在云主机热迁移本身就有应用,即(paused时作为数据包的buffer)避免出现网络断开的情况

同时也解释了为什么恢复checkpoint之后依旧可以有连续的网络,当然考虑到tcp/udp的时候,这里可能对tcp来说更加友好,对使用udp的应用来说排队和保证顺序意义不那么大了

其次是创建checkpoint的时候需要保证I/O一致性需要不停的paused,并且要保证IO请求都sync,感觉也是很麻烦的事情

之后在抽时间看看Qdisc以及qemu虚拟机的IO请求路径,希望能对虚拟化的原理有更好的认识

参考文献

  1. https://wiki.qemu.org/Features/MicroCheckpointing