根据论文《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. Oracle 导出用户下的所有索引创建语句

    SELECT dbms_lob.substr(dbms_metadata.get_ddl('INDEX', INDEX_NAME))||';'  from dba_indexes where owne ...

  2. [Python2]介绍关于Uiautomator的watcher使用场景及使用方法

    [官方的介绍]: Watcher You can register watcher to perform some actions when a selector can not find a mat ...

  3. 网站如何接入第三方登录,微信登录和QQ登录:注册认证篇

    第三方登录平台接入 (QQ\微信登录) QQ登录接入 第一步成为QQ应用开发者,审核期限七天 一.所需材料 1.公司注册相关信息 2.营业执照扫描件 微信登录接入 第一步成为微信开发平台开发者,认证费 ...

  4. 请问下.net俱乐部这个组织现在还存在么?

    各位好,我是北京的一名.net开发人员,一直在想有什么线下技术活动可以开拓自己的视野,扩展人脉,我知道曾经有一个.net俱乐部很活跃 可是现在我在百度上搜了下.net俱乐部的信息,已经基本找不到201 ...

  5. Cobalt Strike深入使用

    System Profiler使用 System Profiler 模块,搜集目标的各类机器信息(操作系统版本,浏览器版本等) Attacks->web drive-by->System ...

  6. 1 TCP/IP通信

    重点参考长链接http://blog.csdn.net/fengyuzhengfan/article/details/38830115 http://blog.csdn.net/Jsagacity/a ...

  7. vue_resource和axios

    vue_resource和axios 1. 简介 vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 axios是一个基于Promise的HTTP请求客户端,用来 ...

  8. 根据Uri获取文件的绝对路径

    简易版处理(实际并没发现有什么问题) public static String getRealPathFromURI(Context context, Uri contentURI) { String ...

  9. 简单的django配置和命令

    1.创建项目:django-admin startproject 项目名称 2.进入项目:cd 项目名称 3.创建子应用:python manage.py startapp 子应用名称 4.把子应用添 ...

  10. CentOS中配置Kafka集群

    环境:三台虚拟机Host0,Host1,Host2 Host0:192.168.10.2 Host1:  192.168.10.3 Host2:  192.168.10.4 在三台虚拟机上配置zook ...