PBFT拜占庭容错算法

Practical byzantine fault tolerance,拜占庭容错算法。PBFT中各节点首先选举出一个leader节点,客户端向leader节点发送请求,leader节点通过广播通知所有副本节点,主节点与副本节点之间通过多次通信,所有准备阶段的节点向所有节点发送最终确认信息,最后所有确认阶段的节点向客户端发送回复信息。PBFT可以很好地解决拜占庭将军问题,但是其无法支持大规模节点,且节点无法自由进出,仅适用于联盟链。

PBFT(Practical byzantine fault tolerance拜占庭容错算法分布式一致性算法:去中心化、大规模节点无法支持、效率低

多个节点中提前选出一个领袖节点,领袖节点代替客户端询问副本节点的意见,客户端最后收集所有节点的意见,进行总结得出最后决定。

Hyperledger有Peer(记账节点:维护账本和状态,上传交易)、Endorsing peer(背书节点:执行智能合约,模拟交易)、Ordering peer(排序节点、共识节点:排序交易,打包交易,生成交易)三种节点

PBFT有leader.validating.non-validating三种节点

如四个节点接收到的顺序不同则先随机选出可能进行了投票机制一个领袖节点其他节点调整到与领袖节点一致

 

PBFT举例:

PBFT算法要求至少要4个参与者,一个被选举为军长,3个师长。军长接到总司令命令:你们向前行军500公里。军长就会给3个师长发命令向前行军500公里。3个师长收到消息后会执行命令,并汇报结果。A师长说我在首都以东500公里,B师长说我在首都以东500公里,C师长说我在首都以东250公里。军长总结3个师长的汇报,发现首都以东500公里占多数(2>1票),所以就会忽略C师长的汇报结果,给总司令汇报说,好了,现在部队是在首都以东500公里了。这就是PBFT算法。

client:请求(request)自愿者,上例中指总司令。

replica:副本,所有参与提供服务的节点,上例指军长和师长

primary:承担起提供服务主要职责的节点,上例是军长

backup:其他副本,但相对于primary角色。上例指师长。

view:处于存在primary-bakup场景中的相对稳定的关系,叫视图。

如果primary出现故障,这种相对稳定的视图关系就会转变(transit)。比如军长叛逃(出现故障,对外表现为不可见),那么某个师长就会转变成为军长。系统也就从视图a转变为视图ba,b均为整数)。

下图展示了在没有发生主节点失效的情况下算法的正常执行流程,其中副本0是主节点,副本3是失效节点,而C是客户端。通过这个例子,也帮助我们理解n>=3f+1的算法。

该算法实现主要分为以下几个步骤:1、客户端向主节点发出请求;2、主节点通过广播通知所有副本节点;3、所有正常副本节点向所有节点(包括主节点)发送请求;4、所有准备阶段的节点向所有节点发送确认信息;5、所有确认阶段的节点向客户端发送回复信息;

 

这是一种基于消息传递的一致性算法,算法经过三个阶段达成一致性,这些阶段可能因为失败而重复进行。

在N ≥ 3F+1 的情况下一致性是可能解决的。其中,N 为计算机总数,F 为有问题计算机总数。信息在计算机间互相交换后,各计算机列出所有得到的信息,以大多数的结果作为解决办法。只要系统中有2/3 的节点是正常工作的,就可以保证一致性。

 

PBFT 算法的过程如下。

客户端向主节点发送请求调用服务。客户端c 向主节点发送<REQUEST,o,t,c> 请求执行操作o,这里时间戳t用来保证客户端请求只会执行一次。每个由副本节点发给客户端的消息都包含了当前的视图编号,使得客户端能够跟踪视图编号,从而进一步推算出当前主节点的编号。客户端通过点对点消息向它自己认为的主节点发送请求,然后主节点自动将该请求向所有备份节点进行广播。

视图是连续编号的整数。主节点由公式p=v mod|R| 计算得到,这里v 是视图编号,p 是副本编号,|R| 是副本集合的个数。副本发给客户端的响应为<REPLY,v,t,c,i,r>,v 是视图编号,t 是时间戳,i 是副本的编号,r 是请求执行的结果。主节点通过广播将请求发送给其他副本,然后就开始执行三个阶段的任务。

(1)预准备阶段。主节点给收到的请求分配一个序列号n,然后向所有备份节点群发预准备消息,预准备消息的格式为<<PRE-PREPARE,v,n,d>,m>,这里v 是视图编号,m是客户端发送的请求消息,d 是请求消息m 的摘要。

(2) 准备阶段。如果备份节点i 接受了预准备消息<<PRE-PREPARE,v,n,d>,m>,则进入准备阶段。在准备阶段时,该节点向所有副本节点发送准备消息<PREPARE,v,n,d,i>,并且将预准备消息和准备消息写入自己的消息日志。如果看预准备消息不顺眼,就什么都不做。

(3) 确认阶段。当(m,v,n,i) 条件为真时, 副本i 将<COMMIT,v,n,D(m),i> 向其他副本节点进行广播,于是就进入了确认阶段。所有副本都执行请求并将结果发回客户端。客户端需要等待f+1 个不同副本节点发回相同的结果,作为整个操作的最终结果。

如果客户端没有在有限时间内收到回复,请求将向所有副本节点进行广播。如果请求已在副本节点处理过了,副本就向客户端重发一遍执行结果。如果请求没有在副本节点处理过,该副本节点将把请求转发给主节点。如果主节点没有将该请求进行广播,那么就有认为主节点失效,如果有足够多的副本节点认为主节点失效,则会触发一次视图变更。

 

拜占庭的问题中,如果总的节点数为N,恶意将军数为F,当N≥3F+1时,拜占庭问题才有解决方法,也就是BFT(Byzantine fault tolerant)算法.

猜你喜欢

转载自blog.csdn.net/Black_BearB/article/details/83215706