超级账本Fabric最新Raft排序服务深度解析

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

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)的组成部分。

image

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

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

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

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

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

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

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

3、Raft共识的基本特性

3.1 Raft节点状态

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

image

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

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

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

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

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

image

3.2 Raft主导节点的选举

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

image

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

image

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

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

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

image

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

image

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

image

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

3.3 日志复制

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

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

image

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

image

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

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

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

image

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
image

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

首先停掉Node3:

docker stop orderer3.example.com
image

然后停掉Node5:

docker stop orderer5.example.com
image

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

image
image
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342