根据论文《Practical Byzantine Fault Tolerance and Proactive Recovery》整理

Practical byzantine fault tolerance and proactive recovery M.Castro and B.Liskov. 2002.

  • 容错\(f\)个节点需要\(3f+1\)个总节点。

状态机复制模型

本算法是基于状态机复制模型的,服务被抽象称为一个状态机,分布式系统的各个节点复制相同的状态,当存在少数节点故障时,状态机依然可以正常运转。

在状态机复制模型中,分布式系统的每个节点都复制完全相同的状态,并支持相同的操作。对于一组相同顺序的输入操作,每个节点都产生相同顺序的输出结果。

BFT算法保证了正常节点在相同的输入下产生相同的输出状态。分布式节点都有一个相同的起始状态,而且每个节点多余相同的输入会产生相同的输入结果。所以,只要保证在分布式系统运行时输入操作的顺序都是一致的,那么各个节点的状态会在运行时始终保持一致。也就是说,对于状态机模型的分布式系统,对输入请求操作的排序是共识算法的关键。

排序机制

本算法采用“Primary-backup”和"Quorum replication"技术结合,来实现任务排序。虽然Paxos和Viewstamped Replication也采用了相同的排序机制,但是本算法可以实现拜占庭容错。

Primary-backup

在“Primary-backup”机制中,各节点都是view的继承表示。在一个View中,其中一个节点作为主节点(Primary)存在,其他节点作为backup。主节点决定操作请求的顺序。主节点给一个请求操作分配一个序列号,并将该分配广播到所有其他节点(backup)。但是主节点也是可能出现错误的,这时需要其他节点来检查序列号,并通过超时检测来确认主节点是否停止工作。一旦检测到当前主节点失败,就会触发View转换,选择一个新的主节点。

算法保证任务序列号是连续的,不能跳跃。当存在View转换时,可以分配序列号给一些空操作,以保证新的主节点内序列号的连续性。

Quorum replication

为了保证系统的容错性能,算法依赖于Quorum机制(大多数原则),Quorum机制有以下两个特性:

  • 任意两个Quorum集合都有至少一个相同正确节点

  • 系统中总是存在一个可访问的无错的Quorum

    Quorum就是一个大多数节点的子集,对于包含四个节点的系统{A, B, C, D},任意三个节点都构成一个Quorum。

Quorum的特性使得它可以作为协议信息的一个可靠存储。节点向Quorum写入信息,同时等待Quorum中节点的验证消息。收到的验证消息可以证明,信息已经被写入成功了。

对于一个节点集合R,我们用整数{0, 1, 2, ... |R|-1}表示每一个节点。简化问题,我们假设|R| = 3f+1,其中f是允许的错误节点个数的最大值。View试图用整数v表示,v也是从小到大的整数。主节点可以用p = v%|R|表示。一般情况下,Quorum是包含至少2f+1个节点的集合。

BFT算法过程

Client发送请求

Client请求一个操作\(o\)时,会向节点广播一个消息\(<Request, o, t, c>\alpha_c\)。其中,\(t\)表示请求发生的时间。对于\(c\)的时间戳用来进行全局排序,需要保证后面的请求有更大的时间戳值。

节点收到请求消息并将其添加到自己的log中,请求的执行及排序在后面的章节描述。节点执行完操作后直接向client发送请求的回复,其回应消息为\(<Reply, v, t, c, i, r>\mu_{ic}\) , \(v\)表示当前View的值,\(t\)是对应请求的时间戳,i表示本节点id,r表示执行的结果。

当client收到了\(f+1\)个带有相同的\(t\)和\(r\)消息时,就接收处理的结果\(r\)。由于最多存在\(f\)个节点发生错误,所以\(f+1\)个节点一致时,就表示该结果的正确的。

如果Client没有收到足够的回应,那么他会重发请求。节点收到请求消息时,如果该消息应景被执行过了,那么就会直接回复该请求,发送一个reply消息。节点需要保存上一次reply的消息,以便后面重发使用。如果主节点没有分配一个有效的序列号,那么就会被足够多的节点认为是一个错误的节点,并触发一次视图转换。

虽然我们假定client是完成当前请求之后,才会触发下一次请求,但是这也很容易扩展到异步的执行请求。

也可以将协议扩展到多个client的情形,给每个client一个秘钥,节点中保存各个client的秘钥。虽然这个方法简单可行,但是当大量client存在时,还是会出现问题。我们做了如下优化,节点值共享存活的client秘钥,而且限制活动的client数量。

请求排序

client发出请求之后的过程,用三个步骤来实现,分别是Pre-prepare、prepare、commit。

节点的状态包含当前service状态、消息log(记录节点收到和发送的消息)、节点当前所处的view(可用整数v表示)。

1. Pre-prepare

当主节点p收到一个来自client的请求 \(m_{\alpha c} = <Request, o, t, c>_{\alpha c}\)时,p会给这个消息\(m\)分配一个序列号\(n\)。之后,p会向其他节点广播一个Pre-prepare消息,并将该消息记录到消息log中。而主节点之外的节点收到消息就直接存在消息log中了。Pre-Prepare的格式可以是\(<Pre-prepare, v, n, D(m)>_{\alpha p}\),其中v表示当前所处的view,D(m)表示消息的哈希值。

与Pre-prepcare阶段一样,其他几个阶段发送的消息中都会包含\(n\)、\(v\)值。节点只会接受与该节点当前所处的view一致的v值的消息。n会用一个区间去判断,即节点会接收符合某个区间的n值的消息。

2. Prepare

当消息m通过验证时,back-up节点会接收一个Pre-prepare消息。如果该节点接收一个Pre-prepare消息,并且该节点的消息log中有对应的\(m\)消息,那么该节点进入Prepare阶段,这时节点会广播Prepare消息\(<Prepare, v, n, D(m), i>_{\alpha i}\), 其中i表示该节点。该节点将收到的Pre-prepare消息和发出的Prepare消息都加入到消息log中。当一个节点收到Pre-prepare消息和2f个符合n, v, m的prepare消息时,该节点就被prepare验证通过,说明该节点prepare了该请求。

协议保证了不会出现有着相同View和序列号n的不同消息通过prepare验证。这保证了在同一个view中的所有消息,都有确定的全局顺序。

假设存在两个不同消息$m$、$m'$通过prepare验证,而他们有着相同的v、n值。根据Quorum原则,一个Quorum中至少有一个节点是正确的。这个节点会发送Pre-prepare或者prepare消息,给在同一个view中的m和m'分配相同的序列号。而根据之前的规定,节点分配序列号应该是累加的,对于不同的消息不应该是相同的序列值。
3. Commit

对于不同view下带有相同序列号的消息来说,commit阶段解决了全局排序的问题。每个节点都广播\(<Commit, v, n, i>_{\alpha_i}\)的commit消息,表明该节点已经经过prepare验证,并将该消息加入消息log中。每个节点都会保持接收commit消息,直到它收到了匹配v和n的2f+1条commit消息,我们叫这个过程为commit验证,验证通过称之为请求被commit了。这个过程之后,节点就同时通过了prepare验证和commit验证。

当请求被commit之后,协议保证请求已经被大多数节点所prepare,也就是说存在一个Quorum知道一个Quorum的节点接受了一个在v视图下的n序列值。这时发生视图转换时,新的主节点可以通过从一个Quorum中读取prepare验证消息,来给新的视图中选择新的序列值n。新的序列值n应该是上一个视图中n的下一个整数。这就可以实现在不同视图下的全局排序了。

当请求被commit之后,节点就会执行消息m对应的操作,节点会根据序列号值从小到大执行操作。所有没有发生错误的节点都会以相同的顺序执行操作。执行完请求操作之后,节点向client发送一个回应信息。为了保证消息只被执行一次,当节点收到比上一次回应的请求消息中的时间戳小的消息时,会忽略。

在这个过程中,没有依赖顺序的消息传送,因此节点commit请求的过程可以是乱序的。

PBFT_拜占庭容错算法的更多相关文章

  1. 实用拜占庭容错算法PBFT

    实用拜占庭容错算法PBFT 实用拜占庭容错算法PBFT 96 乔延宏 2017.06.19 22:58* 字数 1699 阅读 4972评论 0喜欢 11 分布式架构遭遇的问题 分布式架构会遭遇到以下 ...

  2. 一文读懂实用拜占庭容错(PBFT)算法

        在区块链中有一个著名的问题,就是拜占庭将军问题,对于拜占庭将军问题,网上的文章已经多得不要不要了,今天和大家分享的是其相关的实用拜占庭容错算法,一起来看看吧. 实用拜占庭容错算法(Practi ...

  3. 区块链核心技术:拜占庭共识算法之PBFT

    PBFT是Practical Byzantine Fault Tolerance的缩写,意为实用拜占庭容错算法.该算法是Miguel Castro (卡斯特罗)和Barbara Liskov(利斯科夫 ...

  4. 【PBFT】拜占庭容错

    共识机制堪称区块链的核心.我们知道,EOS.Hyperledger以及Stellar等著名的项目,都采用了BFT(拜占庭容错)共识机制,那么,BFT到底是什么鬼?和其它共识机制相比,又有什么优势和特点 ...

  5. 区块链共识算法 PBFT(拜占庭容错)、PAXOS、RAFT简述

    共识算法 区块链中最重要的便是共识算法,比特币使用的是POS(Proof of Work,工作量证明),以太币使用的是POS(Proof of Stake,股权证明)使得算理便的不怎么重要了,而今PO ...

  6. PBFT(拜占庭容错)简述

    共识算法 区块链中最重要的便是共识算法,比特币使用的是POW(Proof of Work,工作量证明),以太币使用的是POS(Proof of Stake,股权证明)使得算力变的不怎么重要了,而今PO ...

  7. 理解分布式一致性:拜占庭容错与PBFT

    理解分布式一致性:拜占庭容错与PBFT 拜占庭问题 拜占庭容错BFT PBFT(Practical Byzantine Fault Tolerance) why 3f+1 ? PBFT 的优点 PBF ...

  8. Filecoin: 影响力容错(PFT)和预期共识(EC)

    名字翻译:Power Fault Tolerance-影响力容错 关于这个名字翻译,小编思考了大约2周时间,期间也跟各路技术牛人进行了交流. The Power Fault Tolerance mod ...

  9. [区块链] 共识算法之争(PBFT,Raft,PoW,PoS,DPoS,Ripple)

    近几天对区块链中几种常见的共识机制(PBFT,Raft,PoW,PoS,DPoS,Ripple)进行了总结.尽量使用简单易懂语言,篇幅较大,想了解的可以只读每个算法介绍中前边的原理.本篇文章主要参考& ...

随机推荐

  1. Mysql查询缓存Query_cache的功用

    MySQL的查询缓存并非缓存执行计划,而是查询及其结果集,这就意味着只有相同的查询操作才能命中缓存,因此MySQL的查询缓存命中率很低,另一方面,对于大结果集的查询,其查询结果可以从cache中直接读 ...

  2. MYSQL导入csv类型的数据出现The MySQL server is running with the --secure-file-priv option

    今天尝试使用 into outfile导出数据的时候出现错误: The MySQL server is running with the --secure-file-priv option so it ...

  3. 2018.08.31 19:41 自学go语言

    有的人是从最基础的开始学,而我却是从最简单开始学,学着调试,学着编程,其实我也是编程小白,好多的不懂,我不明白很多都可以用云完成了,为什么还要继续自己编程,不明白,但是有需求吧,有需求是件好事情,说明 ...

  4. Symbol Tables

    符号表 符号表是键值对的集合,支持给定键查找值的操作,有很多应用: API put() 和 get() 是最基础的两个操作,为了保证代码的一致性,简洁性和实用性,先说下具体实现中的几个设计选择. 泛型 ...

  5. MySql详解(六)

    MySql详解(六) MySql事务 一.含义 事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行 二.特点(ACID) A 原子性:一个事务是不可再分割的整体,要么都执 ...

  6. 洛谷P1208

    #include <iostream>#include <algorithm>#include <cstdio>using namespace std; struc ...

  7. http的长连接和短连接(数据库也一样)

    长连接与短连接 所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持. 短连接是指通信双方有数据交互时 ...

  8. Scala学习之路 (二)使用IDEA开发Scala

    目前Scala的开发工具主要有两种:Eclipse和IDEA,这两个开发工具都有相应的Scala插件,如果使用Eclipse,直接到Scala官网下载即可http://scala-ide.org/do ...

  9. lnmp服务器配置HTTPS

    server { server_name ktsf.weiyou18.com; #listen 80; listen 443; ssl on; ssl_certificate /usr/local/n ...

  10. php中经常使用的string函数

    strpos() ---返回字符串在另一字符串中首次出现的位置 strrpos() ---查找字符串在另一字符串中最后出现的位置 strchr()   ===  strstr()    ---找到字符 ...