在异步系统中,需要主机之间进行状态复制,以保证每个主机达成一致的状态共识。而在异步系统中,主机之间可能出现故障,因此需要在默认不可靠的异步网络中定义容错协议,以确保各个主机达到安全可靠的状态共识。
共识算法其实就是一组规则,设置一组条件,筛选出具有代表性的节点。在区块链系统中,存在很多这样的筛选方案,如在公有链中的POW、Pos、DPOS等,而在不需要货币体系的许可链或私有链中,绝对信任的节点、高效的需求是公有链共识算法不能提供的,对于这样的区块链,传统的一致性共识算法成为首选,如PBFT、PAXOS、RAFT等。
目录
一、BFT(拜占庭容错技术)
二、PBFT(实用拜占庭容错算法)
三、PAXOS
四、Raft
五、POW(工作量证明)
六、POS(权益证明)
七、DPOS(委任权益证明)
八、Ripple
拜占庭弄错技术是一类分布式计算领域的容错技术。拜占庭假设是由于硬件错误、网络拥塞或中断以及遭到恶意攻击的原因,计算机和网络出现不可预测的行为。拜占庭容错用来处理这种异常行为,并满足所要解决问题的规范。
拜占庭容错系统是一个拥有n台节点的系统,整个系统对于每一个请求,满足以下条件:
1)所有非拜占庭节点使用相同的输入信息,产生同样的结果;
2)如果输入的信息正确,那么所有非拜占庭节点必须接收这个信息,并计算相应的结果。
拜占庭系统普遍采用的假设条件包括:
1)拜占庭节点的行为可以是任意的,拜占庭节点之间可以共谋;
2)节点之间的错误是不相关的;
3)节点之间通过异步网络连接,网络中的消息可能丢失、乱序并延时到达,但大部分协议假设消息在有限的时间里能传达到目的地;
4)服务器之间传递的信息,第三方可以嗅探到,但是不能篡改、伪造信息的内容和验证信息的完整性。
拜占庭容错由于其理论上的可行性而缺乏实用性,另外还需要额外的时钟同步机制支持,算法的复杂度也是随节点的增加而指数级增加。
实用拜占庭容错降低了拜占庭协议的运行复杂度,从指数级别降低到多项式级别。
PBFT是一种状态机副本复制算法,即服务作为状态机进行建模,状态机在分布式系统的不同节点进行副本复制。PBFT要求共同维护一个状态。需要运行三类基本协议,包括一致性协议、检查点协议和视图更换协议。
一致性协议。一致性协议至少包含若干个阶段:请求(request)、序号分配(pre-prepare)和响应(reply),可能包含相互交互(prepare),序号确认(commit)等阶段。
PBFT通信模式中,每个客户端的请求需要经过5个阶段。由于客户端不能从服务器端获得任何服务器运行状态的信息,PBFT中主节点是否发生错误只能由服务器监测。如果服务器在一段时间内都不能完成客户端的请求,则会触发视图更换协议。
整个协议的基本过程如下:
1)客户端发送请求,激活主节点的服务 *** 作。
2)当主节点接收请求后,启动三阶段的协议以向各从节点广播请求。
[21]序号分配阶段,主节点给请求赋值一个序列号n,广播序号分配消息和客户端的请求消息m,并将构造PRE-PREPARE消息给各从节点;
[22]交互阶段,从节点接收PRE-PREPARE消息,向其他服务节点广播PREPARE消息;
[23]序号确认阶段,各节点对视图内的请求和次序进行验证后,广播COMMIT消息,执行收到的客户端的请求并给客户端以响应。
3)客户端等待来自不同节点的响应,若有m+1个响应相同,则该响应即为运算的结果。
PBFT一般适合有对强一致性有要求的私有链和联盟链,例如,在IBM主导的区块链超级账本项目中,PBFT是一个可选的共识协议。在Hyperledger的Fabric项目中,共识模块被设计成可插拔的模块,支持像PBFT、Raft等共识算法。
在有些分布式场景下,其假设条件不需要考虑拜占庭故障,而只是处理一般的死机故障。在这种情况下,采用Paxos等协议会更加高效。。PAXOS是一种基于消息传递且具有高度容错特性的一致性算法。
PAXOS中有三类角色Proposer、Acceptor及Learner,主要交互过程在Proposer和Acceptor之间。算法流程分为两个阶段:
phase 1
a) proposer向网络内超过半数的acceptor发送prepare消息
b) acceptor正常情况下回复promise消息
phase 2
a) 在有足够多acceptor回复promise消息时,proposer发送accept消息
b) 正常情况下acceptor回复accepted消息
流程图如图所示:
PAXOS协议用于微信PaxosStore中,每分钟调用Paxos协议过程数十亿次量级。
Paxos是Lamport设计的保持分布式系统一致性的协议。但由于Paxos非常复杂,比较难以理解,因此后来出现了各种不同的实现和变种。Raft是由Stanford提出的一种更易理解的一致性算法,意在取代目前广为使用的Paxos算法。
Raft最初是一个用于管理复制日志的共识算法,它是在非拜占庭故障下达成共识的强一致协议。Raft实现共识过程如下:首先选举一个leader,leader从客户端接收记账请求、完成记账 *** 作、生成区块,并复制到其他记账节点。leader有完全的管理记账权利,例如,leader能够决定是否接受新的交易记录项而无需考虑其他的记账节点,leader可能失效或与其他节点失去联系,这时,重新选出新的leader。
在Raft中,每个节点会处于以下三种状态中的一种:
(1)follower:所有结点都以follower的状态开始。如果没收到leader消息则会变成candidate状态;
(2)candidate:会向其他结点“拉选票”,如果得到大部分的票则成为leader。这个过程就叫做Leader选举(Leader Election);
(3)leader:所有对系统的修改都会先经过leader。每个修改都会写一条日志(log entry)。leader收到修改请求后的过程如下:此过程叫做日志复制(Log Replication)
1)复制日志到所有follower结点
2)大部分结点响应时才提交日志
3)通知所有follower结点日志已提交
4)所有follower也提交日志
5)现在整个系统处于一致的状态
Raft阶段主要分为两个,首先是leader选举过程,然后在选举出来的leader基础上进行正常 *** 作,比如日志复制、记账等。
(1)leader选举
当follower在选举时间内未收到leader的消息,则转换为candidate状态。在Raft系统中:
1)任何一个服务器都可以成为候选者candidate,只要它向其他服务器follower发出选举自己的请求。
2)如果其他服务器同意了,发出OK。如果在这个过程中,有一个follower宕机,没有收到请求选举的要求,此时候选者可以自己选自己,只要达到N/2+1的大多数票,候选人还是可以成为leader的。
3)这样这个候选者就成为了leader,它可以向选民也就是follower发出指令,比如进行记账。
4)以后通过心跳消息进行记账的通知。
5)一旦这个leader崩溃了,那么follower中有一个成为候选者,并发出邀票选举。
6)follower同意后,其成为leader,继续承担记账等指导工作。
(2)日志复制
记账步骤如下所示:
1)假设leader已经选出,这时客户端发出增加一个日志的要求;
2)leader要求follower遵从他的指令,将这个新的日志内容追加到各自日志中;
3)大多数follower服务器将交易记录写入账本后,确认追加成功,发出确认成功信息;
4)在下一个心跳消息中,leader会通知所有follower更新确认的项目。
对于每个新的交易记录,重复上述过程。
在这一过程中,若发生网络通信故障,使得leader不能访问大多数follower了,那么leader只能正常更新它能访问的那些follower服务器。而大多数的服务器follower因为没有了leader,他们将重新选举一个候选者作为leader,然后这个leader作为代表与外界打交道,如果外界要求其添加新的交易记录,这个新的leader就按上述步骤通知大多数follower。当网络通信恢复,原先的leader就变成follower,在失联阶段,这个老leader的任何更新都不能算确认,必须全部回滚,接收新的leader的新的更新。
在去中心账本系统中,每个加入这个系统的节点都要保存一份完整的账本,但每个节点却不能同时记账,因为节点处于不同的环境,接收不同的信息,如果同时记账,必然导致账本的不一致。因此通过同时来决定那个节点拥有记账权。
在比特币系统中,大约每10分钟进行一轮算力竞赛,竞赛的胜利者,就获得一次记账的权力,并向其他节点同步新增账本信息。
PoW系统的主要特征是计算的不对称性。工作端要做一定难度的工作才能得出一个结果,而验证方却很容易通过结果来检查工作端是不是做了相应的工作。该工作量的要求是,在某个字符串后面连接一个称为nonce的整数值串,对连接后的字符串进行SHA256哈希运算,如果得到的哈希结果(以十六进制的形式表示)是以若干个0开头的,则验证通过。
比特币网络中任何一个节点,如果想生成一个新的区块并写入区块链,必须解出比特币网络出的PoW问题。关键的3个要素是 工作量证明函数、区块及难度值 。工作量证明函数是这道题的计算方法,区块决定了这道题的输入数据,难度值决定了这道题所需要的计算量。
(1)工作量证明函数就是<u style="box-sizing: border-box;"> SHA256 </u>
比特币的区块由区块头及该区块所包含的交易列表组成。拥有80字节固定长度的区块头,就是用于比特币工作量证明的输入字符串。
(2)难度的调整是在每个完整节点中独立自动发生的。每2016个区块,所有节点都会按统一的公式自动调整难度。如果区块产生的速率比10分钟快则增加难度,比10分钟慢则降低难度。
公式可以总结为:新难度值=旧难度值×(过去2016个区块花费时长/20160分钟)
工作量证明需要有一个目标值。比特币工作量证明的目标值(Target)的计算公式:目标值=最大目标值/难度值
其中最大目标值为一个恒定值:
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
目标值的大小与难度值成反比。比特币工作量证明的达成就是矿工计算出来的 区块哈希值必须小于目标值 。
(3)PoW能否解决拜占庭将军问题
比特币的PoW共识算法是一种概率性的拜占庭协议(Probabilistic BA)
当不诚实的算力小于网络总算力的50%时,同时挖矿难度比较高(在大约10分钟出一个区块情况下)比特币网络达到一致性的概念会随确认区块的数目增多而呈指数型增加。但当不诚实算力具一定规模,甚至不用接近50%的时候,比特币的共识算法并不能保证正确性,也就是,不能保证大多数的区块由诚实节点来提供。
比特币的共识算法不适合于私有链和联盟链。其原因首先是它是一个最终一致性共识算法,不是一个强一致性共识算法。第二个原因是其共识效率低。
扩展知识: 一致性
严格一致性,是在系统不发生任何故障,而且所有节点之间的通信无需任何时间这种理想的条件下,才能达到。这个时候整个系统就等价于一台机器了。在现实中,是不可能达到的。
强一致性,当分布式系统中更新 *** 作完成之后,任何多个进程或线程,访问系统都会获得最新的值。
弱一致性,是指系统并不保证后续进程或线程的访问都会返回最新的更新的值。系统在数据成功写入之后,不承诺立即可以读到最新写入的值,也不会具体承诺多久读到。但是会尽可能保证在某个时间级别(秒级)之后。可以让数据达到一致性状态。
最终一致性是弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新 *** 作的值。也就是说,如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。
在股权证明PoS模式下,有一个名词叫币龄,每个币每天产生1币龄,比如你持有100个币,总共持有了30天,那么,此时你的币龄就为3000,这个时候,如果你发现了一个PoS区块,你的币龄就会被清空为0。你每被清空365币龄,你将会从区块中获得005个币的利息(假定利息可理解为年利率5%),那么在这个案例中,利息 = 3000 5% / 365 = 041个币,这下就很有意思了,持币有利息。
点点币(Peercoin)是首先采用权益证明的货币。,点点币的权益证明机制结合了随机化与币龄的概念,未使用至少30天的币可以参与竞争下一区块,越久和越大的币集有更大的可能去签名下一区块。一旦币的权益被用于签名一个区块,则币龄将清为零,这样必须等待至少30日才能签署另一区块。
PoS机制虽然考虑到了PoW的不足,但依据权益结余来选择,会导致首富账户的权力更大,有可能支配记账权。股份授权证明机制(Delegated Proof of Stake,DPoS)的出现正是基于解决PoW机制和PoS机制的这类不足。
比特股(Bitshare)是一类采用DPoS机制的密码货币。它的原理是,让每一个持有比特股的人进行投票,由此产生101位代表 , 我们可以将其理解为101个超级节点或者矿池,而这101个超级节点彼此的权利是完全相等的。如果代表不能履行他们的职责(当轮到他们时,没能生成区块),他们会被除名,网络会选出新的超级节点来取代他们。
比特股引入了见证人这个概念,见证人可以生成区块,每一个持有比特股的人都可以投票选举见证人。得到总同意票数中的前N个(N通常定义为101)候选者可以当选为见证人,当选见证人的个数(N)需满足:至少一半的参与投票者相信N已经充分地去中心化。
见证人的候选名单每个维护周期(1天)更新一次。见证人然后随机排列,每个见证人按序有2秒的权限时间生成区块,若见证人在给定的时间片不能生成区块,区块生成权限交给下一个时间片对应的见证人。
比特股还设计了另外一类竞选,代表竞选。选出的代表拥有提出改变网络参数的特权,包括交易费用、区块大小、见证人费用和区块区间。若大多数代表同意所提出的改变,持股人有两周的审查期,这期间可以罢免代表并废止所提出的改变。这一设计确保代表技术上没有直接修改参数的权利以及所有的网络参数的改变最终需得到持股人的同意。
Ripple(瑞波)是一种基于互联网的开源支付协议,在Ripple的网络中,交易由客户端(应用)发起,经过追踪节点(tracking node)或验证节点(validating node)把交易广播到整个网络中。
追踪节点的主要功能是分发交易信息以及响应客户端的账本请求。验证节点除包含追踪节点的所有功能外,还能够通过共识协议,在账本中增加新的账本实例数据。
Ripple的共识达成发生在验证节点之间,每个验证节点都预先配置了一份可信任节点名单,称为UNL(Unique Node List)。在名单上的节点可对交易达成进行投票。每隔几秒,Ripple网络将进行如下共识过程:
1)每个验证节点会不断收到从网络发送过来的交易,通过与本地账本数据验证后,不合法的交易直接丢弃,合法的交易将汇总成交易候选集(candidate set)。交易候选集里面还包括之前共识过程无法确认而遗留下来的交易。
2)每个验证节点把自己的交易候选集作为提案发送给其他验证节点。
3)验证节点在收到其他节点发来的提案后,如果不是来自UNL上的节点,则忽略该提案;如果是来自UNL上的节点,就会对比提案中的交易和本地的交易候选集,如果有相同的交易,该交易就获得一票。在一定时间内,当交易获得超过50%的票数时,则该交易进入下一轮。没有超过50%的交易,将留待下一次共识过程去确认。
4)验证节点把超过50%票数的交易作为提案发给其他节点,同时提高所需票数的阈值到60%,重复步骤3)、步骤4),直到阈值达到80%。
5)验证节点把经过80%UNL节点确认的交易正式写入本地的账本数据中,称为最后关闭账本(Last Closed Ledger),即账本最后(最新)的状态。
在Ripple的共识算法中,参与投票节点的身份是事先知道的。该共识算法只适合于权限链(Permissioned chain)的场景。Ripple共识算法的拜占庭容错(BFT)能力为(n-1)/5,即可以容忍整个网络中20%的节点出现拜占庭错误而不影响正确的共识。
在区块链网络中,由于应用场景的不同,所设计的目标各异,不同的区块链系统采用了不同的共识算法。一般来说,在私有链和联盟链情况下,对一致性、正确性有很强的要求。一般来说要采用强一致性的共识算法。而在公有链情况下,对一致性和正确性通常没法做到百分之百,通常采用最终一致性(Eventual Consistency)的共识算法。
共识算法的选择与应用场景高度相关,可信环境使用paxos 或者raft,带许可的联盟可使用pbft ,非许可链可以是pow,pos,ripple共识等,根据对手方信任度分级,自由选择共识机制。
1 工作量证明(PoW)中本聪在2009年提出的比特币(Bitcoin)是区块链技术最早的应用,其采用PoW作为共识算法,其核心思想是节点间通过哈希算力的竞争来获取记账权和比特币奖励。PoW中,不同节点根据特定信息竞争计算一个数学问题的解,这个数学问题很难求解,但却容易对结果进行验证,最先解决这个数学问题的节点可以创建下一个区块并获得一定数量的币奖励。中本聪在比特币中采用了HashCash[4]机制设计这一数学问题。本节将以比特币采用的PoW算法为例进行说明,PoW的共识步骤如下:
节点收集上一个区块产生后全网待确认的交易,将符合条件的交易记入交易内存池,然后更新并计算内存池中交易的Merkle根的值,并将其写入区块头部;
在区块头部填写如表11所示的区块版本号、前一区块的哈希值、时间戳、当前目标哈希值和随机数等信息;
表11 区块头部信息
随机数nonce在0到232之间取值,对区块头部信息进行哈希计算,当哈希值小于或等于目标值时,打包并广播该区块,待其他节点验证后完成记账;
一定时间内如果无法计算出符合要求的哈希值,则重复步骤2。如果计算过程中有其他节点完成了计算,则从步骤1重新开始。
比特币产生区块的平均时间为10分钟,想要维持这一速度,就需要根据当前全网的计算能力对目标值(难度)进行调整[5]。难度是对计算产生符合要求的区块困难程度的描述,在计算同一高度区块时,所有节点的难度都是相同的,这也保证了挖矿的公平性。难度与目标值的关系为:
难度值=最大目标值/当前目标值 (11)
其中最大目标值和当前目标值都是256位长度,最大目标值是难度为1时的目标值,即2224。假设当前难度为,算力为,当前目标值为,发现新区块的平均计算时间为,则
根据比特币的设计,每产生2016个区块后(约2周)系统会调整一次当前目标值。节点根据前2016个区块的实际生产时间,由公式(14)计算出调整后的难度值,如果实际时间生产小于2周,增大难度值;如果实际时间生产大于2周,则减小难度值。根据最长链原则,在不需要节点同步难度信息的情况下,所有节点在一定时间后会得到相同的难度值。
在使用PoW的区块链中,因为网络延迟等原因,当同一高度的两个区块产生的时间接近时,可能会产生分叉。即不同的矿工都计算出了符合要求的某一高度的区块,并得到与其相近节点的确认,全网节点会根据收到区块的时间,在先收到的区块基础上继续挖矿。这种情况下,哪个区块的后续区块先出现,其长度会变得更长,这个区块就被包括进主链,在非主链上挖矿的节点会切换到主链继续挖矿。
PoW共识算法以算力作为竞争记账权的基础,以工作量作为安全性的保障,所有矿工都遵循最长链原则。新产生的区块包含前一个区块的哈希值,现存的所有区块的形成了一条链,链的长度与工作量成正比,所有的节点均信任最长的区块链。如果当某一组织掌握了足够的算力,就可以针对比特币网络发起攻击。当攻击者拥有足够的算力时,能够最先计算出最新的区块,从而掌握最长链。此时比特币主链上的区块大部分由其生成,他可以故意拒绝某些交易的确认和进行双花攻击,这会对比特币网络的可信性造成影响,但这一行为同样会给攻击者带来损失。通过求解一维随机游走问题,可以获得恶意节点攻击成功的概率和算力之间的关系:
图11 攻击者算力与攻击成功概率
2 权益证明(PoS)
随着参与比特币挖矿的人越来越多,PoW的许多问题逐渐显现,例如随着算力竞争迅速加剧,获取代币需要消耗的能源大量增加,记账权也逐渐向聚集了大量算力的“矿池”集中[6-9]。为此,研究者尝试采用新的机制取代工作量证明。PoS的概念在最早的比特币项目中曾被提及,但由于稳健性等原因没被使用。PoS最早的应用是点点币(PPCoin),PoS提出了币龄的概念,币龄是持有的代币与持有时间乘积的累加,计算如公式(14)所示。利用币龄竞争取代算力竞争,使区块链的证明不再仅仅依靠工作量,有效地解决了PoW的资源浪费问题。
其中持有时间为某个币距离最近一次在网络上交易的时间,每个节点持有的币龄越长,则其在网络中权益越多,同时币的持有人还会根据币龄来获得一定的收益。点点币的设计中,没有完全脱离工作量证明,PoS机制的记账权的获得同样需要进行简单的哈希计算:
其中proofhash是由权重因子、未消费的产出值和当前时间的模糊和得到的哈希值,同时对每个节点的算力进行了限制,可见币龄与计算的难度成反比。在PoS中,区块链的安全性随着区块链的价值增加而增加,对区块链的攻击需要攻击者积攒大量的币龄,也就是需要对大量数字货币持有足够长的时间,这也大大增加了攻击的难度。与PoW相比,采用PoS的区块链系统可能会面对长程攻击(Long Range Attack)和无利害攻击(Nothing at Stake)。
除了点点币,有许多币也使用了PoS,但在记账权的分配上有着不同的方法。例如,未来币(Nxt)和黑币(BlackCion)结合节点所拥有的权益,使用随机算法分配记账权。以太坊也在逐步采用PoS代替PoW。
3 委托权益证明(DPoS)
比特币设计之初,希望所有挖矿的参与者使用CPU进行计算,算力与节点匹配,每一个节点都有足够的机会参与到区块链的决策当中。随着技术的发展,使用GPU、FPGA、ASIC等技术的矿机大量出现,算力集中于拥有大量矿机的参与者手中,而普通矿工参与的机会大大减小。
采用DPoS的区块链中,每一个节点都可以根据其拥有的股份权益投票选取代表,整个网络中参与竞选并获得选票最多的n个节点获得记账权,按照预先决定的顺序依次生产区块并因此获得一定的奖励。竞选成功的代表节点需要缴纳一定数量的保证金,而且必须保证在线的时间,如果某时刻应该产生区块的节点没有履行职责,他将会被取消代表资格,系统将继续投票选出一个新的代表来取代他。
DPoS中的所有节点都可以自主选择投票的对象,选举产生的代表按顺序记账,与PoW及PoS相比节省了计算资源,而且共识节点只有确定的有限个,效率也得到了提升。而且每个参与节点都拥有投票的权利,当网络中的节点足够多时,DPoS的安全性和去中心化也得到了保证。
4 实用拜占庭容错算法(PBFT)
在PBFT算法中,所有节点都在相同的配置下运行,且有一个主节点,其他节点作为备份节点。主节点负责对客户端的请求进行排序,按顺序发送给备份节点。存在视图(View)的概念,在每个视图中,所有节点正常按照处理消息。但当备份节点检查到主节点出现异常,就会触发视图变换(View Change)机制更换下一编号的节点为主节点,进入新的视图。PBFT中客户端发出请求到收到答复的主要流程如图41所示[10] [11],服务器之间交换信息3次,整个过程包含以下五个阶段:
图41 PBFT执行流程
目前以PBFT为代表的拜占庭容错算法被许多区块链项目所使用。在联盟链中,PBFT算法最早是被Hyper ledger Fabric项目采用。Hyperledger Fabric在06版本中采用了PBFT共识算法,授权和背书的功能集成到了共识节点之中,所有节点都是共识节点,这样的设计导致了节点的负担过于沉重,对TPS和扩展性有很大的影响。10之后的版本都对节点的功能进行了分离,节点分成了三个背书节点(Endorser)、排序节点(Orderer)和出块节点(Committer),对节点的功能进行了分离,一定程度上提高了共识的效率。
Cosmos项目使用的Tendermint[12]算法结合了PBFT和PoS算法,通过代币抵押的方式选出部分共识节点进行BFT的共识,其减弱了异步假设并在PBFT的基础上融入了锁的概念,在部分同步的网络中共识节点能够通过两阶段通信达成共识。系统能够容忍1/3的故障节点,且不会产生分叉。在Tendermint的基础上,Hotstuff[13]将区块链的块链式结构和BFT的每一阶段融合,每阶段节点间对前一区块签名确认与新区块的构建同时进行,使算法在实现上更为简单,Hotstuff还使用了门限签名[14]降低算法的消息复杂度。
5 Paxos与Raft
共识算法是为了保障所存储信息的准确性与一致性而设计的一套机制。在传统的分布式系统中,最常使用的共识算法是基于Paxos的算法。在拜占庭将军问题[3]提出后,Lamport在1990年提出了Paxos算法用于解决特定条件下的系统一致性问题,Lamport于1998年重新整理并发表Paxos的论文[15]并于2001对Paxos进行了重新简述[16]。随后Paxos在一致性算法领域占据统治地位并被许多公司所采用,例如腾讯的Phxpaxos、阿里巴巴的X-Paxos、亚马逊的AWS的DynamoDB和谷歌MegaStore[17]等。这一类算法能够在节点数量有限且相对可信任的情况下,快速完成分布式系统的数据同步,同时能够容忍宕机错误(Crash Fault)。即在传统分布式系统不需要考虑参与节点恶意篡改数据等行为,只需要能够容忍部分节点发生宕机错误即可。但Paxos算法过于理论化,在理解和工程实现上都有着很大的难度。Ongaro等人在2013年发表论文提出Raft算法[18],Raft与Paxos同样的效果并且更便于工程实现。
Raft中领导者占据绝对主导地位,必须保证服务器节点的绝对安全性,领导者一旦被恶意控制将造成巨大损失。而且交易量受到节点最大吞吐量的限制。目前许多联盟链在不考虑拜占庭容错的情况下,会使用Raft算法来提高共识效率。
6 结合VRF的共识算法
在现有联盟链共识算法中,如果参与共识的节点数量增加,节点间的通信也会增加,系统的性能也会受到影响。如果从众多候选节点中选取部分节点组成共识组进行共识,减少共识节点的数量,则可以提高系统的性能。但这会降低安全性,而且候选节点中恶意节点的比例越高,选出来的共识组无法正常运行的概率也越高。为了实现从候选节点选出能够正常运行的共识组,并保证系统的高可用性,一方面需要设计合适的随机选举算法,保证选择的随机性,防止恶意节点对系统的攻击。另一方面需要提高候选节点中的诚实节点的比例,增加诚实节点被选进共识组的概率。
当前在公有链往往基于PoS类算法,抵押代币增加共识节点的准入门槛,通过经济学博弈增加恶意节点的作恶成本,然后再在部分通过筛选的节点中通过随机选举算法,从符合条件的候选节点中随机选举部分节点进行共识。
Dodis等人于1999年提出了可验证随机函数(Verifiable Random Functions,VRF)[19]。可验证随机函数是零知识证明的一种应用,即在公私钥体系中,持有私钥的人可以使用私钥和一条已知信息按照特定的规则生成一个随机数,在不泄露私钥的前提下,持有私钥的人能够向其他人证明随机数生成的正确性。VRF可以使用RSA或者椭圆曲线构建,Dodis等人在2002年又提出了基于Diffie-Hellman 困难性问题的可验证随机函数构造方法[20],目前可验证随机函数在密钥传输领域和区块链领域都有了应用[21]。可验证随机函数的具体流程如下:
在公有链中,VRF已经在一些项目中得到应用,其中VRF多与PoS算法结合,所有想要参与共识的节点质押一定的代币成为候选节点,然后通过VRF从众多候选节点中随机选出部分共识节点。Zilliqa网络的新节点都必须先执行PoW,网络中的现有节点验证新节点的PoW并授权其加入网络。区块链项目Ontology设计的共识算法VBFT将VRF、PoS和BFT算法相结合,通过VRF在众多候选节点中随机选出共识节点并确定共识节点的排列顺序,可以降低恶意分叉对区块链系统的影响,保障了算法的公平性和随机性。图灵奖获得者Micali等人提出的Algorand[22]将PoS和VRF结合,节点可以采用代币质押的方式成为候选节点,然后通过非交互式的VRF算法选择部分节点组成共识委员会,然后由这部分节点执行类似PBFT共识算法,负责交易的快速验证,Algorand可以在节点为诚实节点的情况下保证系统正常运行。Kiayias等人提出的Ouroboros[23]在第二个版本Praos[24]引入了VRF代替伪随机数,进行分片中主节点的选择。以Algorand等算法使用的VRF算法为例,主要的流程如下:
公有链中设计使用的VRF中,节点被选为记账节点的概率往往和其持有的代币正相关。公有链的共识节点范围是无法预先确定的,所有满足代币持有条件的节点都可能成为共识节点,系统需要在数量和参与度都随机的节点中选择部分节点进行共识。而与公有链相比,联盟链参与共识的节点数量有限、节点已知,这种情况下联盟链节点之间可以通过已知的节点列表进行交互,这能有效防止公有链VRF设计时可能遇到的女巫攻击问题。
7 结合分片技术的公式算法
分片技术是数据库中的一种技术,是将数据库中的数据切成多个部分,然后分别存储在多个服务器中。通过数据的分布式存储,提高服务器的搜索性能。区块链中,分片技术是将交易分配到多个由节点子集组成的共识组中进行确认,最后再将所有结果汇总确认的机制。分片技术在区块链中已经有一些应用,许多区块链设计了自己的分片方案。
Luu等人于2017年提出了Elastico协议,最先将分片技术应用于区块链中[25]。Elastico首先通过PoW算法竞争成为网络中的记账节点。然后按照预先确定的规则,这些节点被分配到不同的分片委员会中。每个分片委员会内部执行PBFT等传统拜占庭容错的共识算法,打包生成交易集合。在超过的节点对该交易集合进行了签名之后,交易集合被提交给共识委员会,共识委员会在验证签名后,最终将所有的交易集合打包成区块并记录在区块链上。
Elastico验证了分片技术在区块链中的可用性。在一定规模内,分片技术可以近乎线性地拓展吞吐量。但Elastico使用了PoW用于选举共识节点,这也导致随机数产生过程及PoW竞争共识节点的时间过长,使得交易延迟很高。而且每个分片内部采用的PBFT算法通讯复杂度较高。当单个分片中节点数量较多时,延迟也很高。
在Elastico的基础上,Kokoris-Kogias等人提出OmniLedger[26],用加密抽签协议替代了PoW选择验证者分组,然后通过RandHound协议[27]将验证者归入不同分片。OmniLedger。OmniLedger在分片中仍然采用基于PBFT的共识算法作为分片中的共识算法[28],并引入了Atomix协议处理跨分片的交易,共识过程中节点之间通信复杂度较高。当分片中节点数量增多、跨分片交易增多时,系统TPS会显著下降。
Wang等人在2019年提出了Monoxide[29]。在PoW区块链系统中引入了分片技术,提出了连弩挖矿算法(Chu ko-nu mining algorithm),解决了分片造成的算力分散分散问题,使得每个矿工可以同时在不同的分片进行分片,在不降低安全性的情况下提高了PoW的TPS。
Raft算法是解决分布式系统共识的问题的算法,Raft是基于Multi-Paxos的基础上做了简化和限制。不同于Paxos的难以理解,Raft设计的首要目的就是可理解性,一个易于理解、实现简单的分布式一致性协议。
Raft 将一致性算法分解成了几个关键模块,例如选举、日志复制和安全性,本文将主要基于 raft论文 简单分析raft算法。
Raft是强领导(Strong leader)模型,一切以leader为主,比如日志只能由leader复制到其他服务器。所以leader的选举是非常重要的一部分。
首先介绍raft算法的三个服务状态:
任意时间集群中只能由一个leader存在。
Raft使用心跳机制实现leader选举。在服务启动的时候,处于follower角色,需要注意的是每个服务于leader的心跳超时的时间是随机的(150-300 毫秒)。
如上图,集群中有三个几点A、B、C,超时时间分别为150ms、200ms、300ms刚启动时任期编号都是0,都处于follower角色。节点A与leader的心跳超时时间最短,最先从follower状态转为candidate,并增加自己的任期编号,先给自己投上一张选票,并向集群中其他节点发送投票信息,当B、C节点接受到A的投票请求之后,在任期为1的这个阶段没有给其他节点投过票,便接受A的投票请求。此时节点A接受到了集群中超过一半的节点的投票,便成为任期为1的leader。
上诉是最简单的选举流程,里面有很多概念都需要解释,比如为什么超时时间不一样?任期编号是什么?投票比较的规则又是什么?
1 任期编号
每个leader在当选期间都有一个自己的任期编号,它是全局单调递增的数字。每个节点都存储这当前的leader的任期编号,当处于candidate阶段的时候,发起投票的时候会把当前任期编号加一。
而且当一个节点接受到比自己任期高的请求时,会将自己的任期编号更新为高的任期编号,如果当前角色是leader,会从leader转换为follower角色。当接受到任期编号比自己小的请求时,节点会直接拒绝这个请求。
2 投票比较规则
a 先到先服务:一个节点在一个任期只能投一票,如果A、B节点都请求C节点投票,C节点如果先投给A之后、就会拒绝B的投票请求。
b日志完整性:一个节点接受的投票信息如果它的日志比自身小,将会拒绝该投票请求。
c过半策略:当某节点接受到了集群中超过一半的节点投票之后,成为该次任期的leader,向其他节点发送leader心跳。
d 在等待投票期间,candidate 可能会收到另一个声称自己是 leader 的服务器节点发来的 AppendEntries RPC 。如果这个 leader 的任期号(包含在RPC中)不小于 candidate 当前的任期号,那么 candidate 会承认该 leader 的合法地位并回到 follower 状态。
3随机超时
前面提高过,每个几点与leader的心跳超时时间是不同的,这样的好处在于避免瓜分票数的情况存在,能快速的进行leader选举。如果各个节点的超时时间都是一样的,就容易出现瓜分票数的情况存在,每个节点都没有获得超过一半的投票,就会开启下一轮的选举,选举时间就会很长。使用随机超时机制,正常情况下,一个时间段里只有一个节点发起投票请求。
下图是整个集群中服务角色变化的流程图。
Leader选举出来之后为客户端提供服务,将接受到的指令作为一个新的日志项追加到日志中去,然后并行的发起 AppendEntries RPC 给其他的服务器,让它们复制该日志项。当该日志项被安全地复制(过半的节点已复制完成),leader 会应用该日志项到它的状态机中(状态机执行该指令)然后把执行的结果返回给客户端。如果 follower 崩溃或者运行缓慢,或者网络丢包,会不断地重试 AppendEntries RPC(即使已经回复了客户端)直到所有的 follower 最终都存储了所有的日志。
上图展示了日志的格式,一个日志项包含三部分
Leader通过 AppendEntries RPC 将日志复制到其他节点。
AppendEntries RPC:
接收者实现:
上诉是AppendEntries RPC的参数的接受流程。term与leaderId不用介绍很简单,而prevLogIndex、prevLogTerm的作用是日志的一致性检测,如果 follower 在它的日志中找不到包含相同索引位置和任期号的条目,那么他就会拒绝该新的日志条目。一致性检查就像一个归纳步骤:一开始空的日志状态肯定是满足 Log Matching Property(日志匹配特性) 的,然后一致性检查保证了日志扩展时的日志匹配特性。因此,每当 AppendEntries RPC 返回成功时,leader 就知道 follower 的日志一定和自己相同(从第一个日志条目到最新条目)。
正常 *** 作期间,leader 和 follower 的日志保持一致,所以 AppendEntries RPC 的一致性检查从来不会失败。然而,leader 崩溃的情况会使日志处于不一致的状态(老的 leader 可能还没有完全复制它日志里的所有条目)。如下情况:
在 Raft 算法中,leader 通过强制 follower 复制它的日志来解决不一致的问题。这意味着 follower 中跟 leader 冲突的日志条目会被 leader 的日志条目覆盖。
Leader 针对每一个 follower 都维护了一个 nextIndex ,表示 leader 要发送给 follower 的下一个日志条目的索引。当选出一个新 leader 时,该 leader 将所有 nextIndex 的值都初始化为自己最后一个日志条目的 index 加1。如果 follower 的日志和 leader 的不一致,那么下一次 AppendEntries RPC 中的一致性检查就会失败。在被 follower 拒绝之后,leaer 就会减小 nextIndex 值并重试 AppendEntries RPC 。最终 nextIndex 会在某个位置使得 leader 和 follower 的日志达成一致。此时,AppendEntries RPC 就会成功,将 follower 中跟 leader 冲突的日志条目全部删除然后追加 leader 中的日志条目(如果有需要追加的日志条目的话)。一旦 AppendEntries RPC 成功,follower 的日志就和 leader 一致,并且在该任期接下来的时间里保持一致。
本机简单介绍了raft 的leader选举和日志复制,当然raft还有其他的特性本文并没有介绍,推荐去看raft的论文,完整的了解raft。
我之前 ZAB协议 的文章分析了zookeeper的zab协议,这里对比一下两者的异同。
最后 >遇到卡顿了,可以重新更新版本后再次进入。其他问题解决办法如下:1、服务器问题:一次性登录的人数过多导致了服务器崩溃,玩家可退出等待几分钟再进。2、游戏系统问题:游戏系统出现问题,画面一直跳转不出来,玩家可以退出游戏,等待官方解决。3、网络不佳:玩家先测试一下自己的网络存不存在延迟或者无信号的状态。4、游戏版本:玩家可能下载的不是游戏最新版本,可前往应用检查更新或者重新下载。5、游戏卡顿:玩家可以下载加速减少游戏的卡顿。
木筏求生Raft支持玩家联机,游戏中目前还没有对于玩家的联机人数进行限制,8人联机游戏也可以支持,但是对电脑和服务器负担很大,可能会卡顿。
联机相关问题解答
1木筏求生支持玩家联机进行游戏,游戏中目前还没有对于玩家的联机人数进行限制,8人联机游戏也可以支持。
2理论情况下目前联机人数是没有上限的,但是联机人数越多可能游戏内的卡顿问题就会增加。
3玩家们如果想要同时和很多朋友进行联机的话可能需要根据人数来看看游戏内体验是否流畅。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)