mongondb 删除视图失败_重提访问带视图标记的复制

论文地址:重提访问带视图标记的复制 – Liskov & Cowling 2012

本文提出了一个更新版本的viewstamp复制(从现在起称为VR)。虚拟现实工作在一个像互联网这样的异步网络中,处理节点因崩溃而失败的故障。它支持在多个副本节点上运行的复制服务。该服务维护一个状态,并使一组客户机可以访问该状态。VR提供状态机复制:客户端可以运行常规操作来观察和修改服务状态。因此,该方法适合于实现诸如锁管理器或文件系统之类的复制服务。

在这里,我们有一种对Viewstamped复制协议的超级清晰的解释,它使您希望突破编辑器,并立即开始编码它-如果您没有阅读Paxos Made Live当然;)。与我们在周一看到的原始文件相比,除了更清楚的解释外,这个版本还支持重新配置(添加或删除组成员)、一些优化,以及ViewStamped复制(VR)算法和任何可能构建在其上的基于状态机的分布式系统之间的明显区别。

它不同于Paxos,因为它是一个复制协议,而不是一致协议:它使用一致协议,协议与Paxos非常相似,作为支持复制状态机的一部分。另一点是,与Paxos不同,VR在用于执行状态机操作的一致协议期间不需要磁盘I/O

系统的生命周期分为阶段,阶段分为视图。当不在视图或时段之间切换时,系统正常工作。Epoch更改由添加或删除组成员的管理操作驱动(当然,这可能是自动的)。一个epoch内的视图更改是由epoch成员之间的进程或通信失败(假设是暂时的)驱动的。

有四种联锁协议:正常操作、视图更改协议、恢复协议(用于崩溃和恢复副本)和重新配置协议(用于移动到新纪元)。虚拟现实并不介意你在上面构建什么样的状态机——虚拟现实协议负责分发方面,你提供状态机(本文称之为服务)。

当不超过f个副本的故障阈值时,VR确保可靠性和可用性。它通过使用2f+1大小的副本组来实现这一点;这是崩溃故障模型下异步网络中的最小副本数…。一组f+1副本通常称为仲裁,协议的正确性取决于仲裁交叉点属性:处理协议特定步骤的副本的仲裁必须与可用于处理下一步的副本组具有非空交叉点。

正常操作

e5d5e6ebd3ac74e9f94b5c610108028a.png

协议描述假定所有参与的副本都在同一视图中。从一个副本发送到另一个副本的每封邮件都包含发件人的当前viewnumber。副本只处理包含与其知道的视图号匹配的视图号的常规协议消息。如果发送者在后面,接收者会丢弃消息。如果发送方在前面,则复制副本执行状态传输:它请求其他复制副本中缺少的信息,并在处理消息之前使用此信息使自身保持最新。

其中一个副本是主副本,客户端请求被定向到主副本。主订单请求;其他副本是只接受主订单选择的订单的备份。

每个客户机都有一个唯一的客户机id,并为它们发送的每个请求保持一个递增的请求号。客户机向主服务器发送请求消息,要求主服务器执行某些操作,并传递其客户机id和分配的请求号。如果请求号不大于主客户端看到的最大请求号,则它不会处理该请求(但如果是它看到的最新请求,则将重新发送该请求的响应)。

假设主服务器打算处理请求:


主服务器为请求分配下一个操作号并将其添加到其日志中。然后,它向每个副本发送一条prepare消息,其中包含当前视图号、操作号、客户端消息和提交号(最近提交的操作的操作号)。commit号用于在prepare请求的后面存储有关已提交操作的信息。

当备份接收到prepare消息时,它首先等待,直到处理完操作号之前的所有操作(如有必要,使用state catch-up)。然后它将请求添加到日志的末尾,并发送回prepare ok消息。

当主服务器接收到f prepare ok消息时,它将认为操作已提交。它更新其提交号并向服务发出一个up调用,以执行请求的操作。然后向客户端发送回复消息。

通常,副本会在下一条prepare消息中听到提交的消息。如果没有及时的新请求,主服务器可以发送一个提交消息来通知他们。当备份得知某个操作已提交(通过这两种方式之一)时,它首先确保已执行所有先前的操作,然后通过向上调用服务层来执行该操作。(它不向客户端发送回复,主服务器已经这样做了)。

更改视图

原始文件中讨论的keep-alive消息被prepare消息的常规流(当服务繁忙时)替换,或者在安静时提交消息(keep-alive中包含一些有用的信息是有意义的):

备份监视主服务器:他们希望定期收到主服务器的消息。通常,主服务器发送准备消息,但是如果它是空闲的(由于没有请求),它会发送提交消息。如果超时过期而没有来自主节点的通信,则副本将执行视图更改以切换到新的主节点。

这里有一点好奇:没有领导人选举这样选择一个新的初选。在一个纪元内,组成员是固定的(即使有些成员可能无法访问或失败)。假设每一个都有一个唯一的IP地址,并且领导层按照IP地址升序的循环顺序围绕组进行轮换。所以当一个主成员失败时,每个组成员都已经知道哪个成员将成为下一个主成员…

因此,视图更改协议从至少f+1副本的日志中获取信息。这足以确保所有提交的操作都是已知的,因为每个操作都必须至少记录在这些日志中的一个日志中;这里我们依赖quorum intersection属性。未提交的操作也可能存活,但这不是问题:尽可能多的操作存活是有益的。

一个独立地注意到视图更改需要的副本(也就是说,它没有通过来自另一个副本的消息被告知)会前进其视图号,将其状态设置为视图更改,并向所有其他副本发送开始视图更改消息。

当副本接收到具有给定视图号的开始视图更改消息时,它会将视图号与其自身的视图号进行比较。如果视图号高于其自身的视图号,则它会将“开始视图更改”消息发送到具有上述新视图号的所有副本。如果视图编号与其自身匹配,则它会向新的主视图发送do view change消息。(记住,我们已经知道新的初选会是谁了)。作为do view change消息的一部分,复制副本还发送其关键状态:日志、最新操作号和提交号,以及其状态正常的最后一个视图的编号。

当新的主节点接收到f+1 do view change消息(包括来自它自己的消息)时,它会将其状态更新为来自组的最新状态(有精确的规则-有关详细信息,请参阅全文),并启动一个新的视图。它通过将其状态设置为normal并将start view消息发送到其他副本来执行此操作。开始视图消息包括最新状态。

此时,新的主节点可以再次开始处理消息。

当副本接收到“开始”视图消息时,它会根据消息中包含的消息更新其状态,并将其状态设置为“正常”。为了恢复同步,复制副本将准备好的消息发送到新的主节点,用于其日志中任何未提交的操作,并按已知的所有操作的顺序执行以前未执行的操作。

所描述的协议有少量步骤,但有大量消息。我们可以使这些消息变小,但如果我们这样做了,总有可能需要更多的消息。在大多数情况下,获得良好行为的一个合理方法是让副本在其DOVIEWCHANGE消息中包含其日志的后缀。发送的数量可能很小,因为最有可能的情况是新的主服务器是最新的。因此,发送最新的日志条目,或者可能是最新的两个条目就足够了。有时候,这些信息是不够的;在这种情况下,primary可以要求更多的信息,它甚至可能需要首先使用application state来更新自己。

恢复

当副本在崩溃后恢复时,它不能参与请求处理和查看更改,除非它具有至少与失败时相同的最新状态。如果它能比这更早参与,系统可能会失败。

实现这一点的一种方法是在正常操作期间将状态同步持久化到磁盘,但这会减慢整个系统的速度。由于VR复制其他副本的状态,引入恢复协议可以通过网络获取状态,只要副本不发生故障,网络就可以正常工作。与原始VR论文提出的方案不同,这里提出的版本不需要写入磁盘,即使在视图更改期间也是如此。

  • 恢复副本创建一个新的nonce并将包含此nonce的恢复消息发送到所有其他副本。

只有处于正常状态的副本才会响应此消息。主服务器还将发送其状态作为响应的一部分,备份只发送包含nonce的确认。

  • 当副本接收到带有nonce的f+1响应(包括来自主节点的响应)时,它将根据主节点的消息更新其状态,并将状态更改回正常状态。
  • 为了提高恢复效率(避免传输所有日志状态),可以引入检查点。这必须与运行在虚拟现实之上的服务一起完成,因为核心虚拟现实算法对这种状态的本质一无所知。

我们对这个问题的解决方案使用了检查点,并且基于我们稍后关于拜占庭容错的工作。复制代码对应用程序执行的每个O操作都会向上调用,请求它接受一个检查点;这里的O是一个系统参数,大约是100或1000。要获取检查点,应用程序必须在磁盘上记录其状态的快照(此处可以进行后台写入);此外,它还记录一个检查点编号,即检查点中包含的最新操作的操作编号。

使用Merkle树可以有效地管理从另一个副本中获取的应用程序状态,从而只从恢复副本已知的已更改部分中获取更改部分。一旦恢复节点拥有其最新检查点之前的所有状态,它就可以启动恢复协议,包括截至其检查点的操作号-主节点然后仅从该点传输日志。

Epoch变更

处理重新配置的方法如下。重新配置由一个特殊的客户端请求触发。此请求由旧组通过正常情况协议运行。当请求提交时,系统移动到一个新纪元,在这个纪元中,处理客户机请求的责任转移到新组。但是,新组无法处理客户端请求,除非其副本是最新的:新副本必须知道在上一个epoch中提交的所有操作。为了获得最新信息,他们从旧副本传输状态,在状态传输完成之前,旧副本不会关闭。

为了容纳epoch,修改了视图更改和恢复协议,使它们不接受早于当前epoch的epoch的消息。

基本协议现在看起来应该很熟悉了:客户机请求epoch更改操作后,主协议会记录它并发送prepare消息。副本用prepare ok消息进行响应,一旦主副本有f个,它就会通过发送start epoch消息过渡到新epoch。在新纪元内,视图编号将重置回零。新成员必须从现有副本中传输状态,以使自己跟上速度。正在退役的成员将在短时间内继续处理:

被替换的副本响应来自新组中副本的状态传输请求,直到它们从新副本接收到f'+1 EPOCHSTARTED消息,其中f'是新组的阈值。此时,要替换的复制副本将关闭。

当系统从一个纪元移动到下一个纪元时,它不接受任何新的请求。通过在重新配置之前将状态传递给新节点,可以通过“预热”新节点来减少此延迟。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值