MIT6.824/lecture-04-vmware-ft/4.2.md

40 lines
10 KiB
Markdown
Raw Permalink Normal View History

2022-01-25 10:41:31 +08:00
# 4.2 状态转移和复制状态机State Transfer and Replicated State Machine
在VMware FT论文的开始介绍了两种复制的方法一种是状态转移State Transfer另一种是复制状态机Replicated State Machine。这两种我们都会介绍但是在这门课程中我们主要还是介绍后者。
![](<../.gitbook/assets/image (260).png>)
如果我们有一个服务器的两个副本我们需要让它们保持同步在实际上互为副本这样一旦Primary出现故障因为Backup有所有的信息就可以接管服务。状态转移背后的思想是Primary将自己完整状态比如说内存中的内容拷贝并发送给Backup。Backup会保存收到的最近一次状态所以Backup会有所有的数据。当Primary故障了Backup就可以从它所保存的最新状态开始运行。所以状态转移就是发送Primary的状态。虽然VMware FT没有采用这种复制的方法但是假设采用了的话那么转移的状态就是Primary内存里面的内容。这种情况下每过一会Primary就会对自身的内存做一大份拷贝并通过网络将其发送到Backup。为了提升效率你可以想到每次同步只发送上次同步之后变更了的内存。
复制状态机基于这个事实我们想复制的大部分的服务或者计算机软件都有一些确定的内部操作不确定的部分是外部的输入。通常情况下如果一台计算机没有外部影响它只是一个接一个的执行指令每条指令执行的是计算机中内存和寄存器上确定的函数只有当外部事件干预时才会发生一些预期外的事。例如某个随机时间收到了一个网络数据包导致服务器做一些不同的事情。所以复制状态机不会在不同的副本之间发送状态相应的它只会从Primary将这些外部事件例如外部的输入发送给Backup。通常来说如果有两台计算机如果它们从相同的状态开始并且它们以相同的顺序在相同的时间看到了相同的输入那么它们会一直互为副本并且一直保持一致。
所以状态转移传输的是可能是内存而复制状态机会将来自客户端的操作或者其他外部事件从Primary传输到Backup。
![](<../.gitbook/assets/image (261).png>)
人们倾向于使用复制状态机的原因是通常来说外部操作或者事件比服务的状态要小。如果是一个数据库的话它的状态可能是整个数据库可能到达GB这个级别而操作只是一些客户端发起的请求例如读key27的数据。所以操作通常来说比较小而状态通常比较大。所以复制状态机通常来说更吸引人一些。复制状态机的缺点是它会更复杂一些并且对于计算机的运行做了更多的假设。而状态转移就比较简单粗暴我就是将我整个状态发送给你你不需要再考虑别的东西。
有关这些方法有什么问题吗?
> 学生提问如果这里的方法出现了问题导致Primary和Backup并不完全一样会有什么问题
>
> Robert教授假设我们对GFS的Master节点做了多副本其中的Primary对Chunk服务器1分发了一个租约。但是因为我们这里可能会出现多副本不一致所以Backup并没有向任何人发出租约它甚至都不知道任何人请求了租约现在Primary认为Chunk服务器1对于某些Chunk有租约而Backup不这么认为。当Primary挂了Backup接手Chunk服务器1会认为它对某些Chunk有租约而当前的Primary也就是之前的Backup却不这么认为。当前的Primary会将租约分发给其他的Chunk服务器。现在我们就有两个Chunk服务器有着相同的租约。这只是一个非常现实的例子基于不同的副本不一致你可以构造出任何坏的场景和任何服务器运算出错误结果的情形。我之后会介绍VMware的方案是如何避免这一点的。
>
> 学生提问:随机操作在复制状态机会怎么处理?
>
> Robert教授我待会会再说这个问题但是这是个好问题。只有当没有外部的事件时Primary和Backup都执行相同的指令得到相同的结果复制状态机才有意义。对于ADD这样的指令来说这是正确的。如果寄存器和内存都是相同的那么两个副本执行一条ADD指令这条指令有相同的输入也必然会有相同的输出。但是如你指出的一样有一些指令或许是获取当前的时间因为执行时间的略微不同会产生不同的结果。又或者是获取当前CPU的唯一ID和序列号也会产生不同的结果。对于这一类问题的统一答案是Primary会执行这些指令并将结果发送给Backup。Backup不会执行这些指令而是在应该执行指令的地方等着Primary告诉它正确的答案是什么并将监听到的答案返回给软件。
有趣的是或许你已经注意到了VMware FT论文讨论的都是复制状态机并且只涉及了单核CPU目前还不确定论文中的方案如何扩展到多核处理器的机器中。在多核的机器中两个核交互处理指令的行为是不确定的所以就算Primary和Backup执行相同的指令在多核的机器中它们也不一定产生相同的结果。VMware在之后推出了一个新的可能完全不同的复制系统并且可以在多核上工作。这个新系统从我看来使用了状态转移而不是复制状态机。因为面对多核和并行计算状态转移更加健壮。如果你使用了一台机器并且将其内存发送过来了那么那个内存镜像就是机器的状态并且不受并行计算的影响但是复制状态机确实会受并行计算的影响。但是另一方面我认为这种新的多核方案代价会更高一些。
如果我们要构建一个复制状态机的方案我们有很多问题要回答我们需要决定要在什么级别上复制状态我们对状态的定义是什么我们还需要担心Primary和Backup之间同步的频率。因为很有可能Primary会比Backup的指令执行更超前一些毕竟是Primary接收了外部的输入Backup几乎必然是要滞后的。这意味着有可能Primary出现了故障而Backup没有完全同步上。但是让Backup与Primary完全同步执行又是代价很高的操作因为这需要大量的交互。所以很多设计中都关注同步的频率有多高。
如果Primary发生了故障必须要有一些切换的方案并且客户端必须要知道现在不能与服务器1上的旧Primary通信而应该与服务器2上的新Primary通信。所有的客户端都必须以某种方式完成这里的切换。几乎不可能设计一个不出现异常现象的切换系统。在理想的环境中如果Primary故障了系统会切换到Backup同时没有人没有一个客户端会注意到这里的切换。这在实际上基本不可能实现。所以在切换过程中必然会有异常我们必须找到一种应对它们的方法。
如果我们的众多副本中有一个故障了,我们需要重新添加一个新的副本。如果我们只有两个副本,其中一个故障了,那我们的服务就命悬一线了,因为第二个副本随时也可能故障。所以我们绝对需要尽快将一个新的副本上线。但是这可能是一个代价很高的行为,因为副本的状态会非常大。我们喜欢复制状态机的原因是,我们认为状态转移的代价太高了。但是对于复制状态机来说,其中的两个副本仍然需要有完整的状态,我们只是有一种成本更低的方式来保持它们的同步。如果我们要创建一个新的副本,我们别无选择,只能使用状态转移,因为新的副本需要有完整状态的拷贝。所以创建一个新的副本,代价会很高。
以上就是人们主要担心的问题。我们在讨论其他复制状态机方案时,会再次看到这些问题。
让我们回到什么样的状态需要被复制这个话题。VMware FT论文对这个问题有一个非常有趣的回答。它会复制机器的完整状态这包括了所有的内存所有的寄存器。这是一个非常非常详细的复制方案Primary和Backup即使在最底层也是完全一样的。对于复制方案来说这种类型是非常少见的。总的来说大部分复制方案都跟GFS更像。GFS也有复制但是它绝对没有在Primary和Backup之间复制内存中的每一个bit它复制的更多是应用程序级别的Chunk。应用程序将数据抽象成Chunk和Chunk IDGFS只是复制了这些而没有复制任何其他的东西所以也不会有复制其他东西的代价。对于应用程序来说只要Chunk的副本的数据是一致的就可以了。基本上除了VMware FT和一些屈指可数的类似的系统其他所有的复制方案都是采用的类似GFS的方案。也就是说基本上所有的方案使用的都是应用程序级别的状态复制因为这更加高效并且我们也不必陷入这样的困境比如说需要确保中断在Primary和Backup的相同位置执行GFS就完全不需要担心这种情况。但是VMware FT就需要担心这种情况因为它从最底层就开始复制。所以大多数人构建了高效的应用程序级别的复制系统。这样做的后果是复制这个行为必须构建在应用程序内部。如果你收到了一系列应用程序级别的操作你确实需要应用程序参与到复制中来因为一些通用的复制系统例如VMware FT理解不了这些操作以及需要复制的内容。总的来说大部分场景都是应用程序级别的复制就像GFS和其他这门课程中会学习的其他论文一样。
VMware FT的独特之处在于它从机器级别实现复制因此它不关心你在机器上运行什么样的软件它就是复制底层的寄存器和内存。你可以在VMware FT管理的机器上运行任何软件只要你的软件可以运行在VMware FT支持的微处理器上。这里说的软件可以是任何软件。所以它的缺点是它没有那么的高效优点是你可以将任何现有的软件甚至你不需要有这些软件的源代码你也不需要理解这些软件是如何运行的在某些限制条件下你就可以将这些软件运行在VMware FT的这套复制方案上。VMware FT就是那个可以让任何软件都具备容错性的魔法棒。