为了保证安全,除非消息中的请求至少已由f+1个无故障的副本节点执行,并且可以从视图更新中向其他节点证明,否则消息必须保留在副本节点日志中。另外,如果某些副本丢失了所有非故障副本节点丢弃的消息,则需要通过转移全部或部分服务状态来使消息更新。因此,副本也需要一些证明状态正确的证据。
在执行完所有操作之后生成这些证据的代价是昂贵的。相反,当执行的请求序列号可被某个常数(例如100)整除时,这些证据会定期生成。由执行完这些请求后根据状态机的状态产生的称为检查点,稳定的检查点就是该证据。
副本节点维护一些服务状态的逻辑拷贝:最新的稳定的检查点,零个或多个不稳定的检查点,还有当前状态。写时复制技术可以用于减少存储额外状态拷贝的空间负载。
作为证据的正确的检查点由以下步骤产生:
<CHECKPOINT,n,d,i>_s
到其他副本节点。
pre-prepare,prepare,commit
消息中序列号的消息。同时也会抛弃之前所有的检查点以及检查点消息。视图更新协议可以在系统中的primary虚假或崩溃时为系统提供活性。超时则会触发视图更新防止副本节点无限期地等待接收请求去执行。
如果节点i在视图为v时计时器超时,该节点将会开始视图更新并且将视图变为v+1。停止接收信息(除了检查点,视图更新和新视图消息外),并多播<VIEW-CHANGE,v+1,n,C,P,i>_s
消息到所有副本节点。
prepared
集合Pm的集合。pre-prepare
消息(不包括与客户端相关的信息),由不同的副本节点签名的具有相同视图,序列号,m的摘要的prepare
消息。当primary:p在视图v+1时接收到2f个来自其他副本的视图为v+1的有效的VIEW-CHANGE
消息后,将会多播一个<NEW-VIEW,v+1,V,O>_s
消息到所有其他副本节点。
VIEW-CHANGE
消息的集合。VIEW-CHANGE
消息组成的集合。在第一种情况下,primary创建新的消息<PRE-PREPARE,v+1,n,d>_s
,这里的d为在V中序列号为n的高视图编号的pre-prepare
消息的请求摘要。
在第二种情况下,primary将会创建新的<PRE-PREPARE,v+1,n,d_null>_s
消息,这里的d_null为指定的空的请求的摘要。空的请求在协议中和其他请求一样,只不过不进行执行。
NEW-VIEW
消息后,如果签名为正确的,且包含的内容对于视图是v+1是有效的,如果集合O是正确的(O的正确性通过与primary创建O时相同的计算过程进行验证).那么将该信息(正如primary描述的)添加到日志中。,多播在O中的prepare
消息到其他所有副本中,并添加这些prepare
消息到日志中,视图进入v+1。此后,正如三阶段提交协议过程,副本节点重新执行在min-s与max-s中的协议,但是避免重新执行客户端的请求(通过使用存储的关于最新的发送到每一个客户端的回复信息)。
副本可能会缺失某些请求消息m或者是稳定的检查点(由于没有发送NEW-VIEW
消息)。这些缺失的信息可以从其他副本节点获取。
例如,副本i可以从一个副本节点(它的检查点信息已在V中确认正确性)获取缺失的检查点状态s.由于这些f+1个副本节点是正确的,副本节点i将总是获取s或者是最新的稳定检查点。通过对状态进行分区并为每个分区加上被修改的它的最后一个请求的序列号标记,可以避免发送整个检查点。要使副本为最新版本,只需将副本发送到过期的分区,而不是整个检查点。
原文:https://www.cnblogs.com/cbkj-xd/p/12175798.html