【6.824分布式系统笔记】LEC 4: Primary-Backup Replication | 虚拟机、容错、复制状态机、输出控制

这节课基于论文 Fault-Tolerant Virtual Machines,讨论一些关于容错(Fault-Tolerance)和复制(Replication)的问题。

背景

  • 复制

    提高可用性需要进行容错,容错最主要的方法就是复制。

    复制可以处理一些 fail-stop 故障,例如宕机、断网,但是大多数情况下无法处理软件中的 bug 和硬件缺陷。通过纠错码等技术能一定程度处理硬件故障或转换为 fail-stop 故障。

    另外还要注意关联性故障,例如同一批设备可能都有同样的缺陷,或者自然灾害导致整个地区数据中心毁坏。一般需要将副本物理上分开存放。

    复制方案是否值得、需要多少副本是经济问题,需综合考虑。

  • 状态转移和复制状态机

    • VMware FT论文的开始,介绍了两种复制的方法,一种是状态转移(State Transfer),另一种是复制状态机(Replicated State Machine)

      • 状态转移即将 primary 所有状态的变化,包括CPU、内存和I/O设备的变化,几乎连续地传送到 backup 服务器上。
      • 复制状态机即将服务器建模为确定性的状态机,主备机从相同的初始状态开始,确保以相同的顺序接收相同的输入请求来保持同步。同时需要额外的信息协调不确定操作的同步(例如获取时钟、随机数)。使用虚拟机可以做到监控所有的操作。

      也就是说状态转移是完全拷贝,复制状态机是从相同状态开始,只传输改变状态的命令。后者自然对传输的要求小得多。

    • VMware FT论文讨论的都是复制状态机,并且只涉及虚拟机使用单核CPU,因为多核并行处理指令的行为和顺序不确定,不一定产生相同的结果。猜测如果要使用多核只能用状态转移方法。

      即使是使用复制状态机,当有个主机宕机需要一个新的 backup 时,还是只能用状态转移方法。论文用 FT VMotion来在远端机器上克隆primary vm。

  • 复制方式

    • VMware FT论文中,是机器级别复制。复制的是机器的完整状态,这包括了所有的内存,所有的寄存器。Primary和Backup,即使在最底层也是完全一样的。
    • 其他大多数复制方案都是采用的类似GFS,应用程序级别的状态复制,因为这更加高效。但是VMware FT 可以不关心机器上运行什么软件,可以让任何软件都具备容错性。

VMware FT 工作原理

  • 虚拟机

    在物理机硬件上运行一个虚拟机监控器(VMM,Virtual Machine Monitor)或者Hypervisor,这之上可以模拟出多个虚拟的计算机,安装需要的操作系统。

  • VMware FT工作流程

    VMware FT需要两个物理服务器,其中运行着虚拟机,Backup 与 Primary 有着一样的操作系统,二者靠网络连接,并且这两个服务器使用的同一块Disk Server(远程盘)。网络上还连接着许多客户端。

    【6.824分布式系统笔记】LEC 4: Primary-Backup Replication | 虚拟机、容错、复制状态机、输出控制_第1张图片

    • 客户端向 Primary 发送请求,在左边的物理机上产生中断,送到了 VMM,此时 VMM 进行两个操作:
      1. 在虚拟机上模拟中断,数据发给 Primary 的 guest 操作系统。
      2. 拷贝这个请求通过网络(专用的 logging channel)发送给 Backup 的 VMM。从Primary发往Backup的事件被称为Log Channel上的Log Event / Entry
    • Backup 同样模拟中断,发给操作系统。以相同的方式处理这个输入,并保持同步。
    • Primary并通过VMM在虚机内模拟的虚拟网卡发出回复报文,VMM将这个报文发送给客户端。Backup运行相同顺序的指令,但是回复报文会被 VMM 直接丢弃。只有Primary实际生成了回复报文给客户端。
  • 发生故障

    • Primary因为故障停止运行,Backup 将收不到Log Channel上的Log消息(Primary 时钟中断消息都会传给 Backup)。
    • 一段时间没消息且完成之前的log后,Backup虚机会上线(Go Alive)成为新 Primary,将新 Mac 地址广播GARP),并克隆一个新的 Backup。
    • Backup 故障进行类似处理。

非确定性事件同步

  • 非确定性事件

    • **客户端输入。**即一个网络数据包到达,网卡的DMA(Direct Memory Access)将数据拷贝到内存,然后触发中断,操作系统处理此中断。

      对于Primary和Backup,要在相同的时间,相同的位置触发中断。所以不仅需关心网络数据包的内容,还关心中断的时间。

    • 非确定指令。例如生成随机数,获取时间,获取硬件ID。

    • 多核CPU并发。指令顺序是不可预期的,所以不适合使用复制状态机方法。(本论文只要虚拟机单核,不要求物理机)

  • Log 内容

    通过Log Channel的内容论文没说,Robert教授猜测日志条目中有三样东西:

    1. 事件发生时的指令序号。即自机器启动以来指令的相对序号,对于中断和输入来说,指令序号就是指令或者中断在Primary中执行的位置。
    2. Log 类型。网络输入或是特殊指令。
    3. 数据。网络数据包的内容,或是特殊指令在Primary上执行的结果。这样Backup虚机就可以伪造指令,并提供与Primary相同的结果。

    Log channel 两端都有缓冲区,Backup缓冲区为空时不允许执行指令。Backup 会忽略自身物理机上的时钟中断,而是完全由 Log 来伪造中断,使与Primary相同的指令序号位置完全一致。

  • Bounce Buffer

    这个机制就是防止由于操作系统导致失去时序控制,数据包到达后会先拷贝到 Bounce Buffer,此时Primary无法访问,VMM暂停Primary,记录指令序号再拷贝进Primary内存发送中断。Backup 同样在这个序号暂停虚拟机再拷贝进内存发送中断。

输出控制(Output Rule)

  • 前文说过,Primary和Backup都会生成回复报文,通过模拟的网卡送出,但是只有Primary才会真正的将回复送出。但是真实情况还需考虑在尴尬时刻宕机的情况。

    例如客户端对数据10自增,Primary 增到11后回复给客户端,此时崩溃,Backup 没收到Log还是10,变为 Primary后又收到自增请求,回复的还是11。

  • 论文里的解决方法就是控制输出(Output Rule)。直到Backup虚机确认收到了相应的Log条目,Primary虚机不允许生成任何输出。

    即在回复给客户端前先发给 Backup,得到ACK后才能回复客户端。

  • 这里存在的问题是Primary必须停下来等待 Backup,对性能有影响。

这部分学生提了个有趣的问题:能否输入由Primary 处理,输出由Backup处理?

  • 如果 Primary 在回复客户端之前崩溃,只是客户端没得到响应,无影响。如果Primary在回复之后崩溃,Backup 变为 Primary 还会再回复一次客户端(套接字等完全一样),由于是 TCP 协议,所以客户端只用把重复回复当作重传报文丢弃就行了。
  • 对于任何有主从切换的复制系统**,基本上不可能将系统设计成不产生重复输出**。如果没有TCP,那就需要另一种机制,或许是应用程序级别的序列号。
  • 在lab2和lab3中,基本上可以看到前面介绍的所有内容,例如输出控制,你会设计你的复制状态机。

Test-and-Set 解决 Split Brain

  • primary 和backup 之间的网络连接出现故障,但是都在正常运行,此时如果backup 成为primary,就会产生两个primary。即产生脑裂(Split Brain)问题。

    FT的解决方法是在远程共享磁盘上设置一个flag,当primary 或backup 想继续成为primary时,就需要对flag执行原子化的atomic test-and-set操作,就像一个锁,成功则可以成为新的primary,失败则vm停止执行。

  • 每次涉及到主从切换,都需要向Test-and-Set服务进行查询。所以当Backup想要上线的时候,Test-and-Set服务必须要在线。这又会造成**单点故障(Single-Point-of-Failure)**问题。

    Robert教授教授猜测这个也是有容错备份的。

你可能感兴趣的:(分布式系统,golang,分布式,MIT,虚拟机)