Fabric中的RAFT共识算法

什么是共识算法

共识机制(consensus)是所有区块链项目中最基础最根本的成份之一,从简单方便理解的角度来说,可以理解为一种能够保证保持网络中所有账本(ledger)或节点交易的同步和记录一致的机制,就是共识机制。

共识算法各有不同,各有侧重点且各有利弊,在一个分布式网络结构中会有各种各样的异常情况,譬如惰性节点,主机崩溃,无响应和最恶劣的恶意节点。有的算法对恶意节点的攻击有比较强的防御例如PBFT((Practical Byzantine Fault Tolerance)就能在最多三分之一的节点腐化后依然保持出账结果一致,而有的在低延时和高吞吐量方面表现极佳。但总的来说,所有共识算法都有一个共同点,就是只会在交易双方都确认后才进行更新。同时在账本更新时,交易双方能够在账本中的相同位置,更新一个相同的交易信息。

Hyperldger Fabric的不同

Hyperledger Fabric与其他区块链系统最大的不同体现在私有许可。与开放无需许可的网络系统允许未知身份的参与者加入网络不同(需要通过PoW等算法来保证交易有效并维护网络的安全),Hyperledger Fabric通过Membership Service Provider(MSP)来登记所有的成员,且很多联盟链产品都选用此开源平台作为基石。

Hyperledger Fabric也提供了多个可拔插选项。账本数据可被存储为多种格式,共识机制可被接入或者断开,同时支持多种不同的MSP。

Hyperledger Fabric提供了建立channel的功能,这允许参与者为交易新建一个单独的账本。当网络中的一些参与者是竞争对手时,这个功能变得尤为重要。因为这些参与者并不希望所有的交易信息——比如提供给部分客户的特定价格信息——都对网络中所有参与者公开。只有在同一个channel中的参与者,才会拥有该channel中的账本,而其他不在此channel中的参与者则看不到这个账本。

Fabric中的共识算法之Raft

每种共识机制都有它的用武之地,在联盟链的环境下,节点的加入都是经过审核和批准的,所以大大降低了恶意节点的风险,即只有在这种环境下Raft才能使用,因为它是不能防范恶意节点攻击的。类似的算法还有Kafka,Zookeeper和大名鼎鼎的Paxos。PBFT的数学模型论证了若有n个恶意节点,那么系统必须至少包含3n+1个节点来保证结果一致,那么就意味着整个系统更加复杂,而Raft则是在有n个节点发生非拜占庭故障,譬如宕机,网络中断,系统崩溃无响应师,系统仅需要2n+1个节点即能保障顺利运行,大大降低了网络复杂度和部署成本,所以在联盟链这样一个恶意节点存在可能性很小的生产环境下才能使用Raft。

节点状态

  1. 跟随状态(follower):初始情况下,所有的节点都处于跟随状态,也就是都是跟随节点。一旦某个跟随节点没有正常通信,它就转换为候选状态(Candidate),也就是成为一个候选节点。跟随节点的日志可以被主导节点重写。
  2. 候选状态(candidate):处于候选状态的节点会发起选举,如果它收到集群中大多数成员的投票认可,就转换为主导状态。
  3. 主导状态(leader):处理客户端请求并确保所有的跟随节点具有相同的日志副本。主导节点不可以重写其自身的日志。

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

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

主导节点的选举

整个选举通讯是建立在心跳机制之上的。当一个节点启动后是自动变为初始状态即跟随者,当follower能从leader或者candidate那里接受到有效的心跳信息就会一直维持在跟随状态中。而leader也会一直周期性的给所有跟随节点发送心跳信息来维持主导地位。当某个跟随节点在一段时间内没有收到心跳消息时,就发生选举超时事件,该节点就认为目前没有主导节点并发起选举来选出新的主导节点

当一个跟随节点发起选举时,它会递增其任期term并且将状态变化为candidater,然后首先给自己投一票,同时向其他节点发送请求投票的消息(RequestVote RPC消息)。

而候选节点会一直维持候选状态直到出现以下情况:

  1. 此节点胜出成为主导节点。
  2. 其他节点胜出成为主导节点。
  3. 没有节点胜出。

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

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

如果多个候选节点的得票情况相同,那么没有胜出节点。要避免出现这种情况,可以重新初始化选举并确保每个节点的选举超时时长是随机的,以避免跟随节点同时进入候选状态。

日志复制

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

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

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

OSN(Ordering Service Node)的Raft排序实现

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

其工作流程如下:

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

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

Raft和PBFT的对比

RAFT和PBFT的对比
对于 raft 算法,核心共识过程是日志复制这个过程,这个过程分两个阶段,一个是日志记录,一个是提交数据。两个过程都只需要领导者发送消息给跟随者节点,跟随者节点返回消息给领导者节点即可完成,跟随者节点之间是无需沟通的。所以如果集群总节点数为 n,对于日志记录阶段,通信次数为 n-1,对于提交数据阶段,通信次数也为 n-1,总通信次数为 2n-2,因此raft算法复杂度为O(n)。

猜你喜欢

转载自blog.csdn.net/weixin_42918620/article/details/120016355