在当今数字化时代,区块链技术已成为热门话题。以比特币为代表的加密货币虽广为人知,但其底层技术——分布式网络如何达成共识——却少有人深入探究。无论是 Bitcoin、Ethereum 还是 EOS,作为分布式网络,首要解决的是分布式一致性问题:即所有节点如何对同一提案或数值达成共识。这一问题即使在可信节点集群中已颇具挑战,在复杂的区块链网络中更显棘手。
分布式一致性的核心挑战
分布式系统的核心问题在于如何保证集群中所有节点数据完全一致,并对某个提案达成共识。共识算法正是解决这一问题的关键方法。
然而,分布式系统引入多节点后,情况变得复杂多样。随着节点数量增加,节点失效、故障或宕机成为常态。解决各种边界条件和意外情况,极大增加了实现一致性的难度。
除了节点失效,网络通信干扰甚至中断、以及节点运行速度差异,都是实现分布式一致性必须面对的难题。
CAP理论:一致性、可用性与分区容错性的权衡
1998年秋,加州伯克利大学教授 Eric Brewer 首次提出 CAP 理论,随后于1999年发表论文《Brewer’s Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services》,正式阐述了这一理论。
论文证明了两个重要理论:在异步网络模型中,由于节点没有时钟仅能根据接收消息判断,无法同时保证一致性、可用性和分区容错性。每个系统只能在这三种特性中选择两种。
这里讨论的一致性均为强一致性:即所有节点接收相同操作时按完全顺序执行,一个节点提交的更新操作会立即反映在通过异步或部分同步网络连接的其他节点上。若要同时满足一致性和分区容错性,在异步网络中只能中心化存储所有数据,通过其他节点将请求路由至中心节点实现这两个目标。
现实世界中并不存在绝对异步的网络环境。若允许每个节点拥有自己的时钟——即使时间不同但更新频率完全相同——我们就能通过时钟得知接收消息的间隔时间,在这种更宽松的前提下获得更强大的服务。
然而在部分同步网络环境中,我们仍无法同时保证一致性、可用性和分区容错性。证明过程相当简单,可直接阅读论文的4.2节。时钟的出现让我们能知悉当前消息多久未得到回应,通过超时机制在一定程度上解决信息丢失问题。
由于网络必定存在延时,在分布式系统中无法在保证强一致性的同时确保可用性。但我们可以通过降低一致性要求,在一致性和可用性之间做出权衡。这其实是设计分布式系统首先需考虑的问题。强一致性系统会降低系统可用性,仅将接收请求的工作交给其他节点并不能解决高并发服务问题,因此目前主流分布式系统都选择最终一致性。
最终一致性允许多节点状态出现冲突,但所有能通信的节点都能在有限时间内解决冲突,从不一致状态恢复一致。两个条件至关重要:节点可直接正常通信,且冲突需在有限时间内解决。只有满足这两个条件才能达成最终一致性。
拜占庭将军问题:分布式容错的最高挑战
拜占庭将军问题是Leslie Lamport在《The Byzantine Generals Problem》论文中提出的分布式领域容错问题,它是分布式领域最复杂、最严格的容错模型。
在此模型下,系统不对集群中节点做任何限制:它们可向其他节点发送随机数据、错误数据,也可选择不响应其他节点请求。这些无法预测的行为使得容错问题变得异常复杂。
拜占庭将军问题描述了这样一个场景:一组将军分别指挥部分军队,每个将军都不知道其他将军是否可靠,也不知道其他将军传递的信息是否可靠,但它们需要通过投票选择进攻或撤退。
在此场景中,黄色代表状态未知,绿色代表进攻,蓝色代表撤退,红色代表当前将军信息不可靠。
此时,无论将军是否可靠,只要所有将军达成统一方案,选择进攻或撤退都不会有问题。
上述情况不会对战局造成太多影响。但如果其中一个将军告诉部分将军选择进攻,另一部分选择撤退,就会产生严重问题。
由于将军队伍中出现叛徒或信息传递过程被拦截,会导致部分将军选择进攻,另一部分选择撤退,它们都认为自己的选择是多数人的选择,这就出现了严重的不一致问题。
拜占庭将军问题是对分布式系统容错的最高要求。然而这不是日常工作中大多数分布式系统会面对的问题,我们遇到更多的是节点故障宕机或不响应等情况,这大大简化了系统对容错的要求。但类似Bitcoin、Ethereum等分布式系统确实需要考虑拜占庭容错问题,我们将在下文介绍它们如何解决这一挑战。
FLP不可能定理:异步分布式系统的理论限制
FLP不可能定理是分布式系统领域最重要的定理之一,它给出了一个关键结论:在网络可靠且存在节点失效的异步模型系统中,不存在可以解决一致性问题的确定性算法。
论文中指出:完全异步的共识协议甚至无法容忍单个未宣告的进程死亡。我们不考虑拜占庭故障,并假设消息系统可靠——它正确且仅一次传递所有消息。
这一定理告诉我们不要浪费时间设计在任意场景下都能实现共识的异步分布式系统算法。异步系统完全无法保证在有限时间内达成一致。读者可阅读相关论文《Impossibility of Distributed Consensus with One Faulty Process》了解更多内容。
主流共识算法详解
在了解分布式系统面临的问题与挑战后,我们将介绍不同共识算法的实现原理,包括传统分布式系统领域的Paxos、Raft,以及密码货币中使用的工作量证明(POW)、权益证明(POS)和委托权益证明(DPOS)。通过对这些共识算法原理的介绍和分析,读者能对分布式一致性和共识算法有更深入的理解。
Paxos和Raft:非拜占庭系统的一致性解决方案
Paxos和Raft是分布式系统领域中两种著名的解决一致性问题的共识算法。两者都能解决分布式系统中的一致性问题,但前者实现与证明难以理解,后者实现简洁且符合直觉,其出现正是为了解决Paxos难以理解和实现的问题。
Paxos协议家族
Paxos是一类能解决分布式一致性问题的协议,它能让分布式网络中的节点在出现错误时仍保持一致。Leslie Lamport提出的Paxos可在没有恶意节点的前提下保证系统中节点的一致性,也是第一个被证明完备的共识算法。目前完备的共识算法包括Raft本质上都是Paxos的变种。
作为一类协议,Paxos中包含Basic Paxos、Multi-Paxos、Cheap Paxos和其他变种。我们将简要介绍Basic Paxos和Multi-Paxos这两种协议。
Basic Paxos是Paxos中最基础的协议,每个Basic Paxos协议实例最终都会选择唯一结果。使用Paxos作为共识算法的分布式系统中,节点有三种身份:Proposer、Acceptor和Learner。
为简化协议运行过程便于理解,我们忽略最后一种身份Learner。Paxos运行过程分为两个阶段:准备阶段(Prepare)和接受阶段(Accept)。当Proposer接收到客户端请求时,进入以下流程:
在整个共识算法运行过程中,Proposer负责提出提案并向Acceptor发出两次RPC请求:Prepare和Accept。Acceptor根据其持有信息minProposal、acceptedProposal和acceptedValue选择接受或拒绝当前提案。当某提案被过半数Acceptor接受后,我们认为该提案被整个集群接受。
举例说明Paxos如何在多提案下保证最终一致性:S1和S5分别收到客户端请求X和Y,S1首先向S2和S3发出Prepare RPC和Accept RPC,三个服务器都接受S1的提案X。之后,S5向S3和S4服务器发出Prepare(2.5)请求,S3由于已接受X,它会返回接受的提案和值(1.1, X)。这时服务器使用接收到的提案代替自己的提案Y,重新向其他服务器发送Accept(2.5, X)的RPC,最终所有服务器达成一致选择相同值。
Multi-Paxos是Basic Paxos的加强版。由于大多数分布式集群都需要接受一系列值,如果使用Basic Paxos处理数据流会导致明显性能损失。如果集群中Leader稳定,我们往往不需要准备阶段工作,这样就能将RPC数量减少一半。
在稳定阶段Multi-Paxos的处理过程中,S1是整个集群的Leader,当其他服务器接收到客户端请求时,都会将请求转发给Leader处理。
当然,Leader角色的出现带来了新问题:Leader应该如何选举?《Paxos Made Simple》一文中并未给出Multi-Paxos的具体实现方法和细节,因此不同Multi-Paxos实现在总有细微差别。
Raft:更易理解的共识算法
Raft本质上是Multi-Paxos的一个变种,通过简化Multi-Paxos模型,实现了一种更易理解的共识算法。两者都能对一系列连续问题达成一致。
Raft在Multi-Paxos基础上做了两个限制:首先,Raft中追加日志的操作必须是连续的,而Multi-Paxos中追加日志的操作是并发的(但对于节点内部状态机来说两者都是有序的);其次,Raft对Leader选举条件做了限制,只有拥有最新、最全日志的节点才能当选Leader,而Multi-Paxos由于任意节点都可写日志,在选择Leader上没有什么限制,只是在选择Leader后需要将Leader中的日志补全。
在Raft中,所有Follower的日志都是Leader的子集,而Multi-Paxos中的日志不会做此保证。由于Raft对日志追加方式和选举过程进行了限制,实现上更容易和简单。
从理论上讲,支持并发日志追加的Paxos会比Raft有更优秀性能,但其理解和实现仍较复杂。Paxos是科学,而Raft是工程。当需要实现共识算法时,许多人会选择使用Rraft和更简洁的实现,避免因边界条件带来的复杂问题。
POW(工作量证明):拜占庭容错的解决方案
上一节介绍的共识算法,无论是Paxos还是Raft,都只能解决非拜占庭将军容错的一致性问题,无法应对分布式网络中出现的极端情况。但在传统分布式系统中这不是问题,无论是分布式数据库还是消息队列集群,内部节点不会故意发送错误信息。在这些系统中,最常见的问题是节点失去响应或失效,因此上述算法在这种前提下是有效可行且充分的。
工作量证明(POW,Proof-of-Work)是用于阻止拒绝服务攻击和类似垃圾邮件等服务错误问题的协议,1993年由Cynthia Dwork和Moni Naor提出,它能帮助分布式系统达到拜占庭容错。
工作量证明的关键特点是:分布式系统中请求服务的节点必须解决一个一般难度但可行(feasible)的问题,但验证问题答案的过程对服务提供者来说非常容易,即一个不易解答但易验证的问题。
这种问题通常需要消耗一定CPU时间来计算某个问题的答案。目前最大的区块链网络——比特币(Bitcoin)就使用了工作量证明的分布式一致性算法。网络中的所有节点通过计算以下谜题来获得当前区块的记账权:
SHA-256作为哈希函数,目前通过其输出推断输入的可能性可忽略不计。比特币网络需要每个节点不断改变NONCE来得到不同的HASH结果。如果得到的HASH结果小于某个范围(目前难度为0x0000000000000000000000000000000000000000000000000000017268d8a21a),则计算成功。
只计算一次SHA-256的值小于上述结果的可能性是极低的。当前全网算力达到惊人数字,随着网络算力不断改变,比特币会不断调整问题难度,保证每个区块被发现时间在10分钟左右。在整个比特币网络中,谁先得到当前问题的答案就能获得这个区块的记账权,并将当前区块通过Gossip协议发送给尽可能多的比特币节点。
工作量证明原理简单,比特币网络选择的谜题很好适应了工作量证明定义中的问题:难以寻找但易于证明。可以简单理解为工作量证明防止错误或无效请求的原理是增加客户端请求服务的工作量,而合适难度的谜题又能保证合法请求不受影响。
由于工作量证明需要消耗大量算力,同时比特币约10分钟才产生一个区块,区块大小仅1MB,仅能包含3-4000笔交易,平均每秒只能处理5-7笔交易,因此比特币网络拥堵状况非常严重。
POS(权益证明):能效更高的替代方案
权益证明是区块链网络中使用的另一种共识算法。在基于权益证明的密码货币中,下一个区块的选择是根据不同节点的股份和时间进行随机选择的。
由于创建新区块不会消耗大量CPU,如果节点不诚实也不会失去什么,这给了许多节点作弊的理由:每个节点为最大化利益会在多条链上同时挖矿。
在早期所有权证明算法中,整个网络只奖励创建区块的节点,不存在任何惩罚。这时每个节点在创造的多条链上同时投票才能最大化利益,导致网络中节点很难对一条链达成共识。
有两种方法能解决缺乏利害关系(nothing-at-stake)造成的问题:一种是使用Slasher协议,惩罚同时在多条链上投票的节点;第二种是直接惩罚在错误链上创建块的节点。总而言之,通过算法之外的事情解决这个问题,引入激励和惩罚。
与工作量证明相比,权益证明不需要消耗大量电力就能保证区块链网络安全性,同时也不需要在每个区块中创建新货币来激励矿工参与网络运行,这在一定程度上缩短了达成共识所需时间。基于权益证明的Ethereum每秒大概能处理30笔交易左右。
DPOS(委托权益证明):民主化的共识机制
前面介绍的权益证明算法可将整个区块链网络理解为一家公司,出资最多、占比最大的人有更多机会得到话语权(记账权)。对于小股东来说,千分之几甚至万分之几的股份很难有什么作为,只能得到股份带来的分红和收益。
但委托权益证明(DPOS,Delegated Proof-of-Stake)让每个人能选出代表自己利益的人参与记账权争夺,这样多个小股东就能通过投票选出自己的代理人,保障自身利益。整个网络中选举出的多个节点能在1秒内对99.9%的交易进行确认。使用委托权益证明的EOS能够每秒处理几十万笔交易,同时也能比较好地接受监管干预。
在委托权益证明中,每个参与者都能选举任意数量的节点生成下一个区块,得票最多的前N个节点会被选为区块创建者。下一个区块的创建者会从这组当选者中随机选取。此外,N的数量也由整个网络投票决定,从而尽可能保证网络的去中心化。
常见问题
什么是分布式一致性?
分布式一致性指在分布式系统中,所有节点对同一提案或数值达成共识的状态。这是分布式系统正常工作的核心问题,需要通过共识算法来保证各节点数据完全相同并能对某个提案达成一致。
拜占庭将军问题为什么重要?
拜占庭将军问题是分布式领域最复杂、最严格的容错模型,它描述了在有节点可能故意发送错误信息或完全不响应的情况下如何达成共识。这对区块链等需要高度安全性的分布式系统至关重要,是评估共识算法容错能力的最高标准。
POW和POS主要区别是什么?
主要区别在于安全机制和能效。POW依靠算力竞争来保证安全,消耗大量电力;POS依靠节点持有的权益来随机选择记账者,能效更高。POW更适合完全去中心化场景,而POS在效率和可扩展性方面更有优势。
Raft与Paxos有何不同?
Raft是Multi-Paxos的一个变种,通过限制日志追加必须连续且只有拥有最新最全日志的节点才能当选Leader,简化了实现难度。Raft更易于理解和实现,而Paxos理论性能更好但更复杂。Raft被称为"工程",Paxos被称为"科学"。
为什么区块链需要共识算法?
区块链作为去中心化分布式系统,没有中央权威机构决定交易有效性。共识算法使所有节点能就交易顺序和状态变更达成一致,确保网络安全性、一致性和可靠性,防止双重支付等恶意行为。
DPOS如何平衡去中心化与性能?
DPOS通过选举代表节点来执行共识过程,大幅减少参与共识的节点数量从而提高性能。同时,通过全网投票决定代表节点数量和身份,保持一定程度的去中心化。这种设计在性能与去中心化之间取得了实用平衡。
总结
本文系统介绍了分布式系统中面对的核心问题——分布式一致性,并详细分析了五种不同的共识算法。从解决非拜占庭问题下一致性的Paxos和Raft,到解决拜占庭问题下的POW、POS和DPOS,我们发现解决更复杂拜占庭问题的共识算法实现反而更加简单,这是非常有意思的现象。
当整个网络需要实现拜占庭容错时,仅靠算法确实难以实现,往往需要借助其他方面的激励或惩罚机制,让诚实表现的节点利益最大化才是解决一致性的最佳方案。从工作量证明、权益证明到委托权益证明,共识算法的不同导致性能存在显著差异。我们可以看到随着网络中进行"投票"的节点减少,网络处理能力和性能都会提升,委托权益证明通过选举N个节点来保证性能和去中心化程度确实是非常聪明的设计。
中心化网络确实能带来性能提升,但在密码货币中,参与者往往更相信去中心化机制,因为没有激励和惩罚我们不能保证下一个负责记账的节点是否诚实。因此,如何在保证去中心化的同时提升网络性能是每个区块链网络都需要认真考虑的问题。