这篇文章是我看论文《 The Design of a Practical System for Fault-Tolerant Virtual Machines 》时的笔记。这篇论文是VMware发表的论文,利用虚拟机设计分布式容错系统。在分布式系统中,有很多容错方法,常见的传统方法有:primary/secondaryservermethod(当主服务器宕机时,从服务器接管它的工作),这种方法通常需要很高的带宽。还有一种确定性状态机的方法:将另一台服务器初始化为与主服务器相同的状态,然后让它们都接收相同的输入,使它们的状态始终保持一致,但这种方法是针对非确定性的(non-deterministic)操作不适用。本文讨论的方法是将虚拟机作为状态机使用,具有以下优点:对虚拟化后的虚拟机本身的所有操作都支持非确定性操作Hypervision可以记录对虚拟机的所有操作,因此它可以记录主服务器(Primary)的所有操作,然后推导出从服务器(Backup)上的基本设计方案。通信方面,Primary和Backup基本保持同步,Backup稍微落后一点。心跳将用于两者之间的故障检测,它们使用共享磁盘(SharedDisk)。确定性推导让两台机器有相同的初始状态,它们接受相同的输入,以相同的顺序,两台机器执行任务的结果将是相同的。但是如果有非确定性的操作(比如中断事件,读取CPU时钟计数器的值的操作是非确定性的),就会影响状态机的执行。难点在于:需要捕获所有的输入和非确定性操作。为确保备份是确定性的,需要准确地将所有输入和非确定性操作应用于备份。必须保证系统的高效设计。设计方案是:将所有的输入和非确定性操作结合写入日志(文件)。对于非确定性操作,还要记录其相关的状态信息等,确保非确定性操作后备份状态仍然与主一致。FT(Fault-Tolerance)协议是应用于日志通道的协议,该协议的基本要求是:如果Primary宕机,Backup会接管它的工作,然后Backup将所有的Output发送给外部世界必须与Primary应该发送的内容一致。为了保证上述需求,设计了如下系统:Primary在把这个Output的所有信息都发送给Backup之后,再把这个output发送给外界(并保证Backup接收到)。Primary只是延迟将输出发送到外部世界。如图所示,它不会暂停后续任务流程的执行:但是这种方法不能保证输出只发送一次。如果primarycrash了,backup无法判断是在发送输出之前还是之后crash了,所以backup会重新发送输出。但是这个问题很容易解决,因为:输出是通过网络发送的,比如TCP等网络协议可以检测到重复的数据包,即使输出发送了两次也没关系。如果输出是写操作,会在同一个位置写两次,结果不会改变;如果输出是读操作,读到的内容会被放入bouncebuffer(为了消除DMA争用),数据会在IO中断发送到downtimedetection后,怎么知道有机器停机时间在这个系统中非常重要。本设计使用UDP心跳机制来检测Primary和Backup之间的通信是否正常。但是使用这种方式,会出现脑裂问题(split-brain,Primary和Backup同时宕机),如何解决?本设计采用共享存储(SharedStorage),其操作是原子的。Primary和BackupBackup不能同时执行一个操作(提供原子的test-and-set操作)。如果检测到primary宕机,backup就会成为primary,接管之前的工作,然后再寻找backup。具体实现如何启动/重启VirtualMachine来启动一个和Primary状态相同的Backup?VMwareVmotion操作可以将虚拟机从一台服务器完全迁移到另一台服务器(只需要短暂的中断)。本次设计中的方法对Vmotion做了一点修改,不是迁移,而是直接clone。LoggingChannel的管理如图所示。此设计使用大缓冲区来保存日志条目。Primary将自己的条目存储在缓冲区中,loggingchannel将它们发送到Backup缓冲区,然后Backup从缓冲区中读取命令并执行它们。如果备份缓冲区为空且没有执行任何命令,则备份将等待新条目。如果primary的buffer满了,primary会等到buffer有空闲空间再继续执行DiskI/O。磁盘操作是并行的,同时对磁盘的同一个位置进行操作会导致非确定性的解决方案:检测IO竞争,让这些操作串行执行磁盘IO使用DMA(DirectMemoryAccess),而访问内存的同一位置会导致非确定性的解决方案:为磁盘操作的内存设置内存页保护,但这种方法代价太大;本设计中使用了bouncebuffer,其大小与磁盘操作的内存部分大小一致。read操作直接将内容读入buffer,等其他操作完成后写入内存,write操作将写入的内容写入buffer,再写入磁盘。综上所述,Vmware提出的Primary/Backup方法是分布式容错方法中非常重要的一部分,可以在很多系统中使用,不仅可以用于分布式存储(GFS容错方法),还可以用于分布式计算。因为它记录了所有的操作,并在Backup上重新解释,从而起到了备份的作用,并且能够实现容错(Fault-Tolerance)。
