wps序号打乱重新排序_超级账本Fabric最新Raft排序服务深度解析

Raft共识插件是在Hyperledger Fabric 1.4.1后引入的,与之前已有的Solo共识和Kafka共识相比,Raft共识更适合生产环境。本文将介绍共识的基本概念、Raft共识的原理并深入探讨基于Raft共识的 Hyperledger Fabric排序服务。

相关教程:

  • Hyperledger Fabric Node.js开发教程
  • Hyperledger Fabric Java 开发教程

1、共识的基本概念

共识算法可以让机群协同工作,并且可以容忍部分成员主机的故障。通常我们提到主机的故障会区分两种情况对待:拜占庭故障和非拜占庭故障。

比特币是第一个解决了拜占庭故障的去中心化系统,它的方法是使用工作量证明共识(POW)。在一个存在拜占庭故障的系统中,不仅会发生主机崩溃的问题,而且某些成员可能会存在恶意行为去影响整个系统的决策过程。

如果一个分布式系统可以处理拜占庭故障,那么它就可以容忍任何类型的错误发生。常见的支持拜占庭故障的共识算法包括PoW、PoS、PBFT和RBFT。

Raft只能处理非拜占庭故障,也就是说Raft共识可以容忍系统崩溃、网络中断/延迟/包丢失等故障。常见的支持非拜占庭故障的共识算法或系统包括:Raft、Kafka、Paxos和Zookeeper。

那么,Hyperledger Fabric为什么不使用可以容忍拜占庭故障的共识机制呢?那样不是更安全吗?

一个原因在于系统的复杂性与安全性的设计折中。假设一个系统中可能同时有n个节点发生拜占庭故障,那么拜占庭容错要求系统至少有3n+1个节点存在。例如,为了应对100个潜在的恶意节点,你至少需要部署301个节点。这就让系统更复杂。Raft则只需要2n+1个节点来应对潜在的n个节点的非拜占庭故障,显然复杂性和成本要低一些。因此有些分布式系统还是更倾向于Raft,尤其是考虑到像Hyperledger Fabric这种许可制的联盟链环境中,通常会使用数字证书等安全机制来增强安全性,因此存在恶意节点的可能性很小。

2、Raft共识的基本原理

Raft是一个分布式崩溃故障容错共识算法,它可以保证在系统中部分节点出现非拜占庭故障的情况下,系统依然可以处理客户端的请求。从技术上来讲,Raft是一个管理复制日志(Replicated Log)的共识算法,复制日志是复制状态机(RSM:Replicated State Machine)的组成部分。

2139ee3951b389c57c9d09f0cd3cdde3.png

复制状态机是用于构建分布式系统的一种比较基础的架构。它的主要构成单元包括:包含命令序列的节点日志、共识模块(例如Raft)和状态机。

复制状态机的工作原理如下:

ec5c3ec842e07f1938f890cc03264685.png
  1. 客户端向主导节点(Leader Node)发送包含命令的请求
  2. 主导节点将收到的请求追加到其日志中,并将该请求发送给所有的 跟随节点(Follower Node)。跟随节点也会将该请求追加到自身的日志中 并返回一个确认消息
  3. 一旦主导节点收到大部分跟随节点的确认消息,就会将命令日志提交给其管理的状态机。一旦主导节点提交了日志,跟随节点也会将日志提交给自身管理的状态机
  4. 主导节点向客户端返回响应结果

那么,Raft在复制状态机架构中扮演什么角色?

Raft的作用是确保跟随节点的日志与主导节点的日志保持一致(即:日志复制),这样整个分布式系统的行为看起来是一致的,即使部分节点出现故障也没有影响。

另一个问题,客户端是否需要了解哪个是主导节点?

答案是NO,客户端可以向任何一个节点发送请求,如果该节点是主导节点,那么它会直接处理请求,否则的话,该节点会转发请求给主导节点。

3、Raft共识的基本特性

3.1 Raft节点状态

对于Raft算法而言,每个节点只能处于三个状态之一:

48e660ec82dcf2cf62fb9a2c7992a537.png

跟随状态:初始情况下,所有的节点都处于跟随状态,也就是都是跟随节点。一旦某个跟随节点没有正常通信,它就转换为候选状态(Candidate),也就是成为一个候选节点。跟随节点的日志可以被主导节点重写。

候选状态:处于候选状态的节点会发起选举,如果它收到集群中大多数成员的投票认可,就转换为主导状态。

主导状态:处理客户端请求并确保所有的跟随节点具有相同的日志副本。主导节点不可以重写其自身的日志。

如果候选节点发现已经选出了主导节点,它就会退回到跟随状态。同样,如果主导节点发现另一个主导节点的任期(Term)值更高,它也会退回到跟随状态。

任期(Term)是一个单调递增的整数值,用来标识主导节点的管理周期。每个任期都从选举开始,直到下一个任期之前。

4aa658a4a63af30ff76af184d55b6396.png

3.2 Raft主导节点的选举

Raft使用心跳机制来出发主导节点的选举。当节点启动后进入跟随状态,只要它能从主导节点或候选节点收到有效的RPC心跳消息,就会保持在跟随状态。主导节点会周期性发送心跳消息(没有日志项的AppendEntries RPC消息)给所有的跟随节点来维持其主导地位。如果某个跟随节点在一段时间内没有收到心跳消息,就发生选举超时事件,该节点就认为目前没有主导节点并发起选举来选出新的主导节点。

711bb47724ad675e25c6d73103db6450.png

要开始一个选举,跟随节点会递增其当前任期值并转换到候选状态。该节点首先给自己投一票,然后同时向其他节点发送请求投票的消息(RequestVote RPC消息)。

391da2a4cddc485ec9fd27bae847ed98.png

候选节点会保持在候选状态,直到以下事件发生:

  • 该节点胜出选举
  • 其他节点胜出选举
  • 没有节点胜出选举

如果该节点收到大部分节点的投票认可,就可以胜出选举,那么该节点就转换到主导状态成为新的主导节点。注意:每个节点只能投一票。

114749efe5fb53bc8e1356addd1c9364.png

如果同时也有其他节点宣布自己是主导节点并有更高的任期值,那么任期值高的节点成为新的主导节点:

f3d0fc946251fb2b9e50e35ac92da8bd.png

如果多个候选节点的得票情况相同,那么没有胜出节点。

5fb50a1befb83659352d0217bfe552b6.png

要避免出现这种情况,可以重新初始化选举并确保每个节点的选举超时时长是随机的,以避免跟随节点同时进入候选状态。

3.3 日志复制

一旦选出主导节点,它就开始处理客户端的请求。请求中包含有复制状态机需要执行的命令。主导节点将命令追加到自己的日志中,然后并行发送AppendEntriesRPC消息给所有跟随节点复制这个新的日志项。当新的日志项被安全复制后,主导节点会在自身的状态机上执行这个日志项里的命令,并将结果返回给客户端。

如果跟随节点崩溃、运行缓慢或网络发生丢包问题,主导节点会无限重试发送AppendEntries RPC消息(即使它已经向客户端返回了响应结果),直到所有的跟随节点最终得到一致的日志副本。

b603bd98728bfd90d571586e7f2dba83.png

当发送AppendEntries RPC消息时,主导节点会同时发送新日志项的前序日志项的序号和任期值。如果跟随节点在自身日志中没有发现相同的序号和任期值,就会拒绝新的日志项。因此如果pendEntries成功返回,主导节点就知道跟随节点的日志与自己是完全一致的。

9cf87c8aec3d6406dff35b918165c685.png

当出现不一致情况时,主导节点强制跟随节点复制自己的日志。

4、Hyperledger Fabric的Raft排序服务实现

基于Raft的排序服务替代了之前的Kafka排序服务。每个排序节点都有其自己的Raft复制状态机来提交日志。客户端利用Broadcast RPC发送交易提议。Raft排序节点基于共识生成新的区块,当对等节点发送Deliver RPC时,将区块发送给对等节点。

ac7dda00902a2ffbb0914d675cab308f.png

Raft排序节点的工作流程如下:

  1. 交易(例如提议、配置更新)应当自动路由到通道的当前主导节点
  2. 主导节点检查交易验证的配置序列号是否与当前配置序列号一致,如果不一致的 话则执行验证,并在验证失败后驳回交易。通过验证后,主导节点将收到的交易传入区块切割模块的Ordered方法,创建候选区块
  3. 如果产生了新的区块,主导排序节点将其应用于本地的Raft有限状态机(FSM)
  4. 有限状态机将尝试复制到足够数量的排序节点,以便提交区块
  5. 区块被写入接收节点的本地账本

每个通道都会运行Raft协议的单独实例。换句话说,有N个通道的网络,就有N个Raft集群,每个Raft集群都有自己的主导排序节点。

5、基于Raft共识的Hyperledger Fabric网络实战

我们使用BYFN组件展示raft共识模块的使用方法。BYFN包含5个排序节点,2个组织4个对等节点,以及可选的CouchDB。在configtx.yaml文件中给出了Raft排序服务的配置。

用下面的脚本命令启动默认的go链码和raft共识,该脚本会自动生成必要的密码学数据:

cd fabric-samples/first-network
./byfn.sh up -o etcdraft

查看排序服务:

docker logs -f ordrer3.example.com

0c6ec1a099775a2d812b172097fdfea8.png

现在我们验证Raft的容错能力。

首先停掉Node3:

docker stop orderer3.example.com

e31914be8f28464f717e9eeff2b666df.png

然后停掉Node5:

docker stop orderer5.example.com

e36bb74f76c1753e779a7ec41f0519da.png

现在验证系统的有效性,可以看到系统依然可以正常响应客户端的请求:

f247cfd11131f07fc60b119ee361d8d1.png

624e2c65997529a3a58020b009aff6fd.png

原文链接:Hyperledger Fabric Raft共识深度解析 - 汇智网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值