MIT 6.824 分布式系统基础学习(LEC 4-5)

LEC 4 VMware FT(Fault-Tolerant) and Primary-Backup Replication

LEC 5 Go, Threads and Raft


LEC 4 VMware FT(Fault-Tolerant) and Primary-Backup Replication

4.1 Replication

容错本身是为了提供高可用性。复制也不可能是万能的工具,复制能处理什么样的故障呢?

用最简单的方法来描述复制能处理的故障,那就是,单台计算机的fail-stop故障。Fail-stop是一种容错领域的通用术语。它是指,如果某些东西出了故障,比如说计算机,那么它会单纯的停止运行。当任何地方出现故障时,就停止运行,而不是运算出错误结果。

但是复制不能处理软件中的bug和硬件设计中的缺陷。以MapReduce的Master节点为例,如果在Master程序里面有一个bug,那么复制对我们没有任何帮助,因为我们在两台计算机上的MapReduce Master都会计算出相同的错误结果,其他组件都会接受这个错误的结果。类似的,我们也不能期望复制可以处理硬件的漏洞。

当然,也有一些硬件和软件的bug是可以被复制处理掉的。就是那些让服务stop的bug,例如其他不相关的软件导致服务器崩溃,这个时候副本会取而代之。总的来说,我们还是只能期望复制能够处理fail-stop错误。

对于复制,还有一些其他的限制。如果我们有两个副本,我们总是假设两个副本中的错误是相互独立的。例如,我们从同一个厂商买了数千台完全一样的计算机,我们将我们的副本运行在这些同一时间,同一地点购买的计算机上,这还是有一点风险的。因为如果其中一台计算机有制造缺陷,那么极有可能其他的计算机也有相同的缺陷,这是一种关联错误。另一种情况。比如,数据中心所在的城市发生了地震,摧毁了整个数据中心,无论我们在那个数据中心里有多少副本,都无济于事。所以,如果我们想处理类似地震引起的问题,我们需要将我们的副本放在不同的城市,或者至少物理上把它们分开,这样它们会有独立的供电,不会被同样的自然灾害影响。

解决了复制能处理什么故障的问题,另一个问题是,复制这种方案是否值得?

GFS对于每个数据块都有3份拷贝,所以我们需要购买实际容量3倍的磁盘。VMware FT复制了一份,意味着我们需要两倍的计算机,CPU,内存。这些东西都不便宜,所以自然会有这个问题,这里的额外支出真的值得吗?

这不是一个可以从技术上来回答的问题,这是一个经济上的问题,它取决于一个可用服务的价值。如果你在运行一个银行系统,这种情况下,你可以有一个额外的副本。但是另一方面,如果是这个课程的网站,我不认为它值得拥有一个热备份。所以,对于系统做复制是否值得,该复制多少份,你愿意为复制花费多少,都取决于失败会给你带来多大的损失和不便。

4.2 State Transfer and Replicated State Machine

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

状态转移。如果有一个服务器的两个副本,我们需要让它们保持同步,在实际上互为副本,这样一旦Primary出现故障,因为Backup有所有的信息,就可以接管服务。状态转移就是Primary将自己完整状态,完整拷贝并发送给Backup。Backup会保存收到的最近一次状态,所以Backup会有所有的数据。当Primary故障了,Backup就可以从它所保存的最新状态开始运行。所以,状态转移就是发送Primary的状态。虽然VMware FT没有采用这种复制的方法,但是假设采用了的话,那么转移的状态就是Primary内存里面的内容。这种情况下,每过一会,Primary就会对自身的内存做一大份拷贝,并通过网络将其发送到Backup。为了提升效率,你可以想到每次同步只发送上次同步之后变更了的内存。

复制状态机基于这个事实:我们想复制的大部分的服务或者计算机软件都有一些确定的内部操作,不确定的部分是外部的输入。通常情况下,如果一台计算机没有外部影响,它只是一个接一个的执行指令,每条指令执行的是计算机中内存和寄存器上确定的函数,只有当外部事件干预时,才会发生一些预期外的事。所以,复制状态机不会在不同的副本之间发送状态,相应的,它只会从Primary将这些外部事件,发送给Backup。通常来说,如果有两台计算机,如果它们从相同的状态开始,并且它们以相同的顺序,在相同的时间,看到了相同的输入,那么它们会一直互为副本,并且一直保持一致。

所以,状态转移传输的是可能是内存,而复制状态机会将来自客户端的操作或者其他外部事件,从Primary传输到Backup。人们倾向于使用复制状态机的原因是,外部操作或者事件比服务的状态要小。如果是一个数据库的话,它的状态可能是整个数据库,而操作只是一些客户端发起的请求。所以操作通常来说比较小,而状态通常比较大。复制状态机的缺点是,它会更复杂一些,并且对于计算机的运行做了更多的假设。而状态转移就比较简单粗暴,我就是将我整个状态发送给你,你不需要再考虑别的东西。

VMware FT论文讨论的都是复制状态机,并且只涉及了单核CPU。在多核的机器中,两个核交互处理指令的行为是不确定的,所以就算Primary和Backup执行相同的指令,在多核的机器中,它们也不一定产生相同的结果。VMware在之后推出了一个新的可能完全不同的复制系统,并且可以在多核上工作。这个新系统从我看来使用了状态转移,而不是复制状态机。因为面对多核和并行计算,状态转移更加健壮。如果你使用了一台机器,并且将其内存发送过来了,那么那个内存镜像就是机器的状态,并且不受并行计算的影响,但是复制状态机确实会受并行计算的影响。但是另一方面,我认为这种新的多核方案代价会更高一些。

我们还需要担心Primary和Backup之间同步的频率,因为很有可能Primary会比Backup的指令执行更超前一些,毕竟是Primary接收了外部的输入,Backup几乎必然是要滞后的。这意味着,有可能Primary出现了故障,而Backup没有完全同步上。但是,让Backup与Primary完全同步执行又是代价很高的操作,因为这需要大量的交互。所以,很多设计中,都关注同步的频率有多高。

如果Primary发生了故障,客户端需要跟新的primary通信,所有客户端都必须以某种方式完成这里的切换。在理想的环境中,如果Primary故障了,系统会切换到Backup,没有一个客户端会注意到这里的切换。

如果只有两个副本,其中一个故障了,那我们的服务就命悬一线了,所以我们绝对需要尽快将一个新的副本上线。但是这可能是一个代价很高的行为,因为副本的状态会非常大。我们喜欢复制状态机的原因是,我们认为状态转移的代价太高了。如果我们要创建一个新的副本,我们别无选择,只能使用状态转移,因为新的副本需要有完整状态的拷贝。所以创建一个新的副本,代价会很高。

什么样的状态需要被复制这。VMware FT会复制机器的完整状态,Primary和Backup,即使在最底层也是完全一样的。对于复制方案来说,这种类型是非常少见的,大部分复制方案都跟GFS更像。GFS也有复制,但是它绝对没有在Primary和Backup之间复制内存中的每一个bit,它复制的更多是应用程序级别的Chunk。应用程序将数据抽象成Chunk和Chunk ID,GFS只是复制了这些,而没有复制任何其他的东西,所以也不会有复制其他东西的代价。对于应用程序来说,只要Chunk的副本的数据是一致的就可以了。基本上除了VMware FT和一些屈指可数的类似的系统,其他所有的复制方案都是采用的类似GFS的方案。也就是说基本上所有的方案使用的都是应用程序级别的状态复制,因为这更加高效,并且我们也不必陷入这样的困境,比如说需要确保中断在Primary和Backup的相同位置执行,GFS就完全不需要担心这种情况。但是VMware FT就需要担心这种情况,因为它从最底层就开始复制。所以,大多数人构建了高效的,应用程序级别的复制系统。这样做的后果是,复制这个行为,必须构建在应用程序内部。如果你收到了一系列应用程序级别的操作,你确实需要应用程序参与到复制中来,因为一些通用的复制系统,例如VMware FT,理解不了这些操作,以及需要复制的内容。总的来说,大部分场景都是应用程序级别的复制,就像GFS和其他这门课程中会学习的其他论文一样。

VMware FT的独特之处在于,它从机器级别实现复制,因此它不关心你在机器上运行什么样的软件,它就是复制底层的寄存器和内存。你可以在VMware FT管理的机器上运行任何软件,只要你的软件可以运行在VMware FT支持的微处理器上。这里说的软件可以是任何软件。所以,它的缺点是,它没有那么的高效,优点是,你可以将任何现有的软件,甚至你不需要有这些软件的源代码,你也不需要理解这些软件是如何运行的,在某些限制条件下,你就可以将这些软件运行在VMware FT的这套复制方案上。VMware FT就是那个可以让任何软件都具备容错性的魔法棒。

4.3 How VMware FT Work?

4.4 Non-Deterministic Events

4.5 Output Rule

4.6 Duplicated Output

4.7 Test-and-Set Service

LEC 5 Go, Threads and Raft