分布式系统 - 基于虚拟机的主从复制

分布式系统 - 基于虚拟机的主从复制

本文主要参考论文《The Design of a Practical System for Fault-Tolerant Virtual Machines》和MIT6.824 lecture4而写。本文将这篇论文简写为VM-FT

1 VM-FT原理

1. 为什么要主从复制?

当一台服务器挂掉后,应该怎么办呢?其中一个解决方案是,提前复制这台服务器。本文将原始服务器称为主机,将复制的服务器称为从机

1.2 复制方式

复制一台服务器的方式有两种:

  • 状态转移:主机将自己所有的状态(包括CPU、内存、I\O设备等)全部发给从机。
  • 复制状态机:两台服务器以同样的状态启动。当客户端向主机发送请求时,主机将该请求原封不动地发送给从机。这样,主机和从机以同样的状态启动,且以同样的顺序执行同样的命令,那么它们的结果自然也就一样了。

显然,状态转移这种方式传输的数据量比复制状态机这种方式要大得多。因此,VM-FT选择使用了复制状态机方式进行复制。

1.3 VM-FT结构

VM-FT是基于虚拟机实现的主从复制,其结构如下图所示。其中,主机和从机处在同一个网络中,且共用一个磁盘。主机接收到的命令,将通过Logging channel传给从机。随后,主机和从机都会执行这些命令以保持一致。
VM-FT结构

1.4 确定性重放

我们现在已经知道了主机复制的大概原理,但是要真正实现完全的主从复制还有三大难点:

  • 主机正确获取所有的输入和非确定性输入
  • 从机执行主机传来的所有输入和非确定输入,并获得和主机一致的结果
  • 在实现上述两个目标的同时,还不能降低系统的性能

VM-FT中提到VMware deterministic replay技术解决了这些难点,具体可见论文《ReTrace: Collecting Execution Trace with Virtual Machine Deterministic Replay》。

1.5 FT协议

现在,我们思考一种情况。主机中有一个数据为10。这时,客户端发送了一个请求,想要将这个数据加一。主机接收了这个请求,将这个数据+1得到了11,并将这个11返回给了客户端。突然,主机崩溃了,且还没有给从机发送客户端的这个请求。由于主机崩溃了,从机接管了主机,但是从机还未收到主机的+1指令,因此从机的这个数据仍然是10。这是,客户端又发送了一个加1的请求,但接管的从机中存的数据仍然是10,那么返回给客户端的数据仍然是11。客户端此时就觉得很奇怪了,明明请求了两次加1,为什么得到的结果只加了1次呢?

为了避免上述的问题,VM-FT提出了FT协议。该协议制定了输出规则,规则如下:

  • 主机在将得到的输出发送给客户端之前,需要收到从机传来的确认请求(确保从机收到了主机传去的同步消息)。
  • 主机在确定要将输出发送给客户端之前,不会停滞,而是会执行后面的任务。(这样就可以将等待的时间利用起来了)

FT协议的时间序列图如下图所示:
FT协议
现在,我们再思考一种情况。当主机收到了从机的确认请求,且将输出发给了客户端后,主机挂掉了。此时,从机开始接管,但从机不知道主机是否发送了输出给客户端,那该怎么办呢?VM-FT提到,既然输出是通过网络发送的,那TCP之类的网络协议是可以检测出重复的数据包的。

1.6 监测并处理故障

监测

通过UDP心跳包Logging channel,主机和从机可以快速知道另一方是否出现故障。UDP心跳包是定时发送的一个自定义的结构体,用来让对方知道自己还在运行。Logging channel中,有主机向从机发送的日志记录,也有从机向主机发送的确认信息。如果UDP心跳包和Logging channel的信息超过一段时间没有被检测到,就认为有故障发生了。

处理故障

当我们检测到故障后,从机是不是会想接管主机来运行呢?但如果这样的故障是因为网络的问题引起的,而不是主机出现问题呢?此时,主机和从机都在运行了。那与这台主机交互的客户端就会收到多个回复,这样就不对了,这个问题就是split-brain问题。为了避免split-brain问题,VM-FT在共享存储上(主机和从机共享一个磁盘,见VM-FT结构图)执行一个原子指令test-and-set。该指令伪代码如下:

test-and-set() {
    acquire_lock()
    if flag == true:
      release_lock()
      return false
    else:
      flag = true
      release_lock()
      return true
}

当主机还在运行时,flag已经被设置为true了。此时,从机想去接管的话,需要去查询这个flag变量,发现flag已经为true了,从机就不会接管了。这样,也就避免了split-brain的问题。

2 VM-FT的具体实现细节

2.1 创建从机

前面我们说到从机需要和主机以同样的状态启动,那么怎么样让从机和主机以同样的状态启动呢?VMware公司提供了一个名为VMware VMotion的工具,该工具允许以最小化中断的代价,将正在运行的虚拟机从一台服务器迁移到另一台服务器上。该操作只需要不到1秒的时间就能完成。为了实现备份的目的,VM-FT对VMotion工具做了略微的修改。VM-FT让VMotion在另一台服务器上创建一个虚拟机备份后,并不销毁当前服务器的虚拟机。

2.2 管理Logging Channel

主机和从机各自有一个Log buffer,主机将产生的日志写入主机的Log buffer,然后通过Logging channel传给从机的Log buffer,从机再从自己的Log buffer中读取日志。

当从机的Log buffer空了的时候,从机会等待,直到主机给从机传了日志才会继续执行。这不会有任何问题。但当主机的Log buffer满了,会发生什么呢?主机必须等到Log buffer中的日志被消耗了,才能继续写。这样的话,连接该服务器的客户端会长时间收不到回复,因为主机一直在等待从机消耗Log buffer中的日志。此外,当主机在这种情况下崩溃的时候,从机需要重放很多主机传来的日志,才能继续接管主机。这也会严重影响用户的体验。

为了解决这个问题,VM-FT在FT协议中的发送信息和确认信息中,额外添加了信息(比如主机和从机执行同一个命令的时间)来计算主机和从机执行同一个命令的时间差。如果时间差过大(比如说超过1s),VM-FT就会通知CPU调度器,让其给主机更少的CPU执行时间。

2.3 其他

VM-FT还有更多的实现细节,本文不再继续展开。如果你感兴趣,可以参考原论文《The Design of a Practical System for Fault-Tolerant Virtual Machines》。

3 VM-FT与GFS的容错性比较

  • VM-FT备份的是计算,GFS备份的是存储。
  • VM-FT提供了较为严谨的一致性。可以用它为任何已有的网络服务器提供容错。例如,VM-FT 应用于一个已有的邮件服务器,为其提供容错性。
  • GFS 只针对简单的服务提供容错性,它的备份策略比 FT 更为高效。例如,GFS 不需要让所有的操作都应用在所有的备份上。

参考

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值