Raft协议
在很多分布式系统场景下,并不需要解决拜占庭将军问题,也就是说,在这些分布式系统的实用场景下,其假设条件不需要考虑拜占庭故障,而只是处理一般的死机故障。在这种情
况下,采用Paxos等协议会更加高效。Paxos是Lamport设计的保持分布式系统一致性的协议。但由于Paxos非常复杂,比较难以理解,因此后来出现了各种不同的实现和变种。例如谷
歌的GFS、BigTable就采用了基于Paxos的Chubby的分布式锁协议;Yahoo的Hadoop系统采用了类似Paxos协议的Zookeeper协议。Raft也是为了避免Paxos的复杂性而专门设计成易于理
解的分布式一致性算法。在私有链和联盟链的场景下,通常共识算法有强一致性要求,同时对共识效率要求高。另外一般安全性要比公有链场景高,一般来说不会经常存在拜占庭故
障。因此,在一些场景下,可以考虑采用非拜占庭协议的分布式共识算法。
在Hyperledger的Fabric项目中,共识模块被设计成可插拔的模块,支持像PBFT、Raft等共识算法。
Raft最初是一个用于管理复制日志的共识算法 [1] ,它是一个为真实世界应用建立的协议,主要注重协议的落地性和可理解性。Raft是在非拜占庭故障下达成共识的强一致协议。
在区块链系统中,使用Raft实现记账共识的过程可以描述如下:首先选举一个leader,接着赋予leader完全的权力管理记账。leader从客户端接收记账请求,完成记账操作,生成区
块,并复制到其他记账节点。有了leader简化了记账操作的管理。例如,leader能够决定是否接受新的交易记录项而无需考虑其他的记账节点,leader可能失效或与其他节点失去联
系,这时,系统就会选出新的leader。
给定leader方法,Raft将共识问题分解为三个相对独立的子问题。
·leader选举:现有的leader失效时,必须选出新leader。
·记账:leader必须接受来自客户端的交易记录项,在参与共识记账的节点中进行复制,并使其他的记账节点认可交易所对应的区块。
·安全:若某个记账节点对其状态机应用了某个特定的区块项,其他的服务器不能对同一个区块索引应用不同的命令。
1.Raft基础
一个Raft集群通常包含5个服务器,允许系统有两个故障服务器。每个服务器处于3个状态之一:leader、follower或candidate。正常操作状态下,仅有一个leader,其他的服务器
均为follower。follower是被动的,不会对自身发出请求而是对来自leader和candidate的请求做出响应。leader处理所有的客户端请求(若客户端联系follower,则该follower将
转发给leader)。candidate状态用来选举leader。
Raft阶段主要分为两个,首先是leader选举过程,然后在选举出来的leader基础上进行正常操作,比如日志复制、记账等。
2.leader选举
当follower在选举超时时间内未收到leader的心跳消息,则转换为candidate状态。为了避免选举冲突,这个超时时间是一个150~300ms之间的随机数。
一般而言,在Raft系统中:
1)任何一个服务器都可以成为一个候选者candidate,它向其他服务器follower发出要求选举自己的请求。
2)其他服务器同意了,发出OK。注意,如果在这个过程中,有一个follower宕机,没有收到请求选举的要求,此时候选者可以自己选自己,只要达到N/2+1的大多数票,候选人还是
可以成为leader的。
3)这样这个候选者就成为了leader领导人,它可以向选民也就是follower发出指令,比如进行记账。
4)以后通过心跳进行记账的通知。
5)一旦这个leader崩溃了,那么follower中有一个成为候选者,并发出邀票选举。
6)follower同意后,其成为leader,继续承担记账等指导工作。
3.记账过程
Raft的记账过程按以下步骤完成:
1)假设leader领导人已经选出,这时客户端发出增加一个日志的要求;
2)leader要求follower遵从他的指令,都将这个新的日志内容追加到他们各自日志中;
3)大多数follower服务器将交易记录写入账本后,确认追加成功,发出确认成功信息;
4)在下一个心跳中,leader会通知所有follower更新确认的项目。
对于每个新的交易记录,重复上述过程。
如果在这一过程中,发生了网络通信故障,使得leader不能访问大多数follower了,那么leader只能正常更新它能访问的那些follower服务器。而大多数的服务器follower因为没有
了leader,他们将重新选举一个候选者作为leader,然后这个leader作为代表与外界打交道,如果外界要求其添加新的交易记录,这个新的leader就按上述步骤通知大多数follower
,如果这时网络故障修复了,那么原先的leader就变成follower,在失联阶段,这个老leader的任何更新都不能算确认,都回滚,接收新的leader的新的更新。