想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】 链客,有问必答!!
分布式系统核心问题
随着摩尔定律遇到瓶颈,愈来愈多状况下要依靠分布式架构,才能实现海量数据处理能力和可扩展计算能力。
区块链系统,首先是一个分布式系统。传统单节点结构演变到分布式系统,碰到的首要问题就是一致性的保障。很显然,若是分布式集群没法保证处理结果一致的话,那任何创建于其上的业务系统都没法正常工做。
本文将介绍分布式系统领域的核心问题,包括一致性、共识的定义,基本的原理和算法,另外还介绍了评估分布式系统可靠性的指标。
1、一致性问题
一致性问题是分布式领域最为基础也是最重要的问题。若是分布式系统能实现“一致”,对外就能够呈现为一个完美的、可扩展的“虚拟节点”,相对物理节点具有更优越性能和稳定性。这也是分布式系统但愿能实现的最终目标。
1.一、定义与重要性
定义:一致性(consistency),早期也叫agreement,是指对于分布式系统中的多个服务节点,给定一系列操做,在约定协议的保障下,试图使得它们对处理结果达成“某种程度”的认同。
理想状况下,若是各个服务节点严格遵循相同的处理协议,构成相同的处理状态机,给定相同的初始状态和输入序列,则能够保障在处理过程当中的每一个环节的结果都是相同的。
那么,为何说一致性问题十分重要呢?
举个现实生活中的例子,多个售票处同时出售某线路上的火车票,该线路上存在多个经停站,怎么才能保证在任意区间都不会出现超售(同一个座位卖给两我的)的状况呢?
这个问题看起来彷佛没那么难,现实生活中常常经过分段分站售票的机制。然而,为了支持海量的用户和避免出现错误,存在不少设计和实现上的挑战。特别在计算机的世界里,为了达到远超普通世界的高性能和高可扩展性需求,问题会变得更为复杂。
注意:一致性并不表明结果正确与否,而是系统对外呈现的状态一致与否;例如,全部节点都达成失败状态也是一种一致。
1.二、问题与挑战
看似强大的计算机系统,实际上不少地方都比人类世界要脆弱得多。特别是在分布式计算机集群系统中,以下几个方面很容易出现问题:
节点之间的网络通讯是不可靠的,包括消息延迟、乱序和内容错误等;
节点的处理时间没法保障,结果可能出现错误,甚至节点自身可能发生宕机;
同步调用能够简化设计,但会严重下降分布式系统的可扩展性,甚至使其退化为单点系统。
仍以火车票售卖问题为例,愿意动脑筋的读者可能已经想到了一些不错的解决思路,例如:
要出售任意一张票前,先打电话给其余售票处,确认下当前这张票不冲突。即经过同步调用来避免冲突;
多个售票处提早约好隔离的售票时间。好比第一家能够在上午8点到9点期间卖票,接下来一个小时是另一家……即经过令牌机制来避免冲突;
成立一个第三方的存票机构,票集中存放,每次卖票前找存票机构查询。此时问题退化为中心化单点系统。
固然,还会有更多方案。
实际上,这些方案背后的思想,都是将可能引起不一致的并行操做进行串行化。这实际上也是现代分布式系统处理一致性问题的基础思路。只是由于如今的计算机系统应对故障每每不够“智能”,而人们又但愿系统能够更快更稳定地工做,因此实际可行的方案须要更加全面和更加高效。
注意:这些思路都没有考虑请求和答复消息出现失败的状况,同时假设每一个售票处的售票机制是正常工做的。
1.三、一致性要求
规范地说,分布式系统达成一致的过程,应该知足:
可终止性(termination):一致的结果在有限时间内能完成;
约同性(agreement):不一样节点最终完成决策的结果是相同的;
合法性(validity):决策的结果必须是某个节点提出的提案;
可终止性很容易理解。有限时间内完成,意味着能够保障提供服务(liveness)。这是计算机系统能够被正常使用的前提。须要注意,在现实生活中这点并非总能获得保障的。例如取款机有时候会出现“服务中断”;拨打电话有时候是“没法链接”的。
约同性看似容易,实际上暗含了一些潜在信息。决策的结果相同,意味着算法要么不给出结果,任何给出的结果一定是达成了共识的,即安全性(safety)。挑战在于算法必需要考虑的是可能会处理任意的情形。凡事一旦推广到任意情形,每每就不像看起来那么简单。例如如今就剩一张某区间(如北京–>南京)的车票了,两个售票处也分别刚经过某种方式确认过这张票的存在。这时,两家售票处几乎同时分别来了一个乘客要买这张票,从各自“观察”看来,本身一方的乘客都是先到的……这种状况下,怎么能达成对结果的共识呢?看起来很容易,卖给物理时间上率先提交请求的乘客便可。然而,对于两个来自不一样位置的请求来讲,要判断在时间上的“前后”关系并非那么容易。两个车站的时钟多是不一致的;可能没法记录下足够精确的时间;更况且根据相对论的观点,并不存在绝对的时空观。
可见,事件发生的前后顺序十分重要,这也是解决分布式系统领域不少问题的核心秘诀:把多件事情进行排序,并且这个顺序还得是你们都承认的。
最后一个合法性看似绕口,可是其实比较容易理解,即达成的结果必须是节点执行操做的结果。仍以卖票为例,若是两个售票处分别决策某张票出售给张三和李四,那么最终达成一致的结果要么是张三,要么是李四,而绝对不能是其余人。
1.四、带约束的一致性
从前面的分析能够看到,要实现绝对理想的严格一致性(strict consistency)代价很大。除非系统不发生任何故障,并且全部节点之间的通讯无需任什么时候间,这个时候整个系统其实就等价于一台机器了。实际上,越强的一致性要求每每会形成越弱的处理性能,以及越差的可扩展性。
通常来说,强一致性(strong consistency)主要包括下面两类:算法
顺序一致性(sequential consistency):Leslie Lamport在1979年的经典论文《How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Programs》中提出,是一种比较强的约束,保证全部进程看到的全局执行顺序(total order)一致,而且每一个进程看自身的执行顺序(local order)跟实际发生顺序一致。例如,某进程先执行A,后执行B,则实际获得的全局结果中就应该为A在B前面,而不能反过来。同时全部其余进程在全局上也应该看到这个顺序。顺序一致性实际上限制了各进程内指令的偏序关系,但不在进程间按照物理时间进行全局排序;数据库
线性一致性(linearizability consistency):Maurice P.Herlihy与Jeannette M.Wing在1990年的经典论文《Linearizability:A Correctness Condition for Concurrent Objects》中共同提出,在顺序一致性前提下增强了进程间的操做排序,造成惟一的全局顺序(系统等价因而顺序执行,全部进程看到的全部操做的序列顺序都一致,而且跟实际发生顺序一致),是很强的原子性保证。可是比较难实现,目前基本上要么依赖于全局的时钟或锁,要么经过一些复杂算法实现,性能每每不高。安全
实现强一致性每每须要准确的计时设备。高精度的石英钟的偏移率为10的-7次方,最准确的原子震荡时钟的偏移率为10的负13次方。Google曾在其分布式数据库Spanner中采用基于原子时钟和GPS的“TrueTime”方案,可以将不一样数据中心的时间误差控制在10ms之内。方案简单粗暴并且有效,但存在成本较高的问题。
因为强一致性的系统每每比较难实现,并且不少时候,实际需求并无那么严格须要强一致性。所以,能够适当地放宽对一致性的要求,从而下降系统实现的难度。例如在必定约束下实现所谓最终一致性(eventual consistency),即总会存在一个时刻(而不是马上),让系统达到一致的状态。大部分Web系统实现的都是最终一致性。相对强一致性,这一类在某些方面弱化的一致性都笼统称为弱一致性(weak consistency)。
2、共识算法
共识(consensus)在不少时候会与一致性(consistency)术语放在一块儿讨论。严谨地讲,二者的含义并不彻底相同。
一致性每每指分布式系统中多个副本对外呈现的数据的状态。如前面提到的顺序一致性、线性一致性,描述了多个节点对数据状态的维护能力。而共识则描述了分布式系统中多个节点之间,彼此对某个状态达成一致结果的过程。所以,一致性描述的是结果状态,共识则是一种手段。达成某种共识并不意味着就保障了一致性。
实践中,要保障系统知足不一样程度的一致性,核心过程每每须要经过共识算法来达成。
共识算法解决的是对某个提案(proposal)你们达成一致意见的过程。提案的含义在分布式系统中十分宽泛,如多个事件发生的顺序、某个键对应的值、谁是领导……等等。能够认为任何能够达成一致的信息都是一个提案。对于分布式系统来说,各个节点一般都是相同的肯定性状态机模型(又称为状态机复制问题,state-machine replication),从相同初始状态开始接收相同顺序的指令,则能够保证相同的结果状态。所以,系统中多个节点最关键的是对多个事件的顺序进行共识,即排序。
2.一、问题与挑战
实际上,若是分布式系统中各个单节点都能保证以十分“理想”的性能(瞬间响应、超高吞吐)无端障地运行,节点之间通讯瞬时送达,则实现共识过程并不十分复杂,简单地经过广播进行瞬时投票和应答便可。
惋惜的是,现实中这样的“理想”系统并不存在。不一样节点之间通讯存在延迟(光速物理限制,通讯处理延迟),而且任意环节均可能存在故障(系统规模越大,发生故障可能性越高)。如通讯网络会发生中断、节点会发生故障、甚至存在恶意节点故意要伪造消息,破坏系统的正常工做流程。
通常地,把出现故障(crash或fail-stop,即不响应)但不会伪造信息的状况称为“非拜占庭错误”(non-byzantine fault)或“故障错误”(Crash Fault);伪造信息恶意响应的状况称为“拜占庭错误”(Byzantine Fault),对应节点为拜占庭节点。
2.二、常见算法
根据解决的是非拜占庭的普通错误状况仍是拜占庭错误状况,共识算法能够分为Crash Fault Tolerance(CFT)类算法和Byzantine Fault Tolerance(BFT)类算法。
针对常见的非拜占庭错误的状况,已经存在一些经典的解决算法,包括Paxos、Raft及其变种等。这类容错算法每每性能比较好,处理较快,容忍不超过一半的故障节点。
对于要能容忍拜占庭错误的状况,通常包括PBFT(Practical Byzantine Fault Tolerance)为表明的肯定性系列算法、PoW为表明的几率算法等。对于肯定性算法,一旦达成对某个结果的共识就不可逆转,即共识是最终结果;而对于几率类算法,共识结果则是临时的,随着时间推移或某种强化,共识结果被推翻的几率愈来愈小,成为事实上的最终结果。拜占庭类容错算法每每性能较差,容忍不超过1/3的故障节点。
此外,XFT(Cross Fault Tolerance)等最近提出的改进算法能够提供相似CFT的处理响应速度,并能在大多数节点正常工做时提供BFT保障。
注意:实践中,一致性的结果每每还须要客户端的额外支持,典型状况如经过访问足够多个服务节点来比对验证,确保获取共识后的正确结果。
2.三、理论界限
数学家都喜欢对问题先肯定一个最坏的理论界限。那么,共识问题的最坏界限在哪里呢?很不幸,在推广到任意情形时,分布式系统的共识问题无通用解。这彷佛很容易理解,当多个节点之间的通讯网络自身不可靠的状况下,很显然,没法确保实现共识(例如,全部涉及共识的消息都在网络上丢失)。那么,对于一个设计得当,能够大几率保证消息正确送达的网络,是否是就必定能保证达成共识呢?
科学家们证实,即使在网络通讯可靠状况下,可扩展的分布式系统的共识问题,其通用解法的理论下限是——没有下限(无解)。
这个结论称为“FLP不可能原理”。该原理极其重要,能够看作是分布式领域里的“测不许原理”。
提示:不只在分布式系统领域,实际上在不少领域都存在相似“测不许原理”的约束。
3、FLP不可能原理
3.一、定义
FLP不可能原理:在网络可靠,但容许节点失效(即使只有一个)的最小化异步模型系统中,不存在一个能够解决一致性问题的肯定性共识算法(No completely asynchronous consensus protocol can tolerate even a single unannounced process death)。
提出并证实该定理的论文《Impossibility of Distributed Consensus with One Faulty Process》由Fischer、Lynch和Patterson三位科学家于1985年发表,该论文后来得到了Dijkstra(就是发明最短路径算法的那位计算机科学家)奖。
FLP不可能原理实际上告诉人们,不要浪费时间,去为异步分布式系统设计在任意场景下都能实现共识的算法。
3.二、正确理解
要正确理解FLP不可能原理,首先要弄清楚“异步”的含义。
在分布式系统中,同步和异步这两个术语存在特殊的含义。
同步是指系统中的各个节点的时钟偏差存在上限;而且消息传递必须在必定时间内完成,不然认为失败;同时各个节点完成处理消息的时间是必定的。对于同步系统,能够很容易地判断消息是否丢失。
异步是指系统中各个节点可能存在较大的时钟差别,同时消息传输时间是任意长的,各节点对消息进行处理的时间也多是任意长的,这就形成没法判断某个消息迟迟没有被响应是哪里出了问题(节点故障仍是传输故障?)。不幸地是,现实生活中的系统每每都是异步系统。
FLP不可能性在原始论文中以图论的形式进行了严格证实。要理解这一基本原理并不复杂,一个不严谨的例子以下。
三我的在不一样房间进行投票(投票结果是0或者1)。彼此能够经过电话进行沟通,但常常有人会时不时睡着。好比某个时候,A投票0,B投票1,C收到了两人的投票,而后C睡着了。此时,A和B将永远没法在有限时间内获知最终的结果,到底是C没有应答仍是应答的时间过长。若是能够从新投票,则相似情形能够在每次取得结果前发生,这将致使共识过程永远没法完成。
FLP原理实际上说明对于容许节点失效状况下,纯粹异步系统没法确保一致性在有限时间内完成。即使对于非拜占庭错误的前提下,包括Paxos、Raft等算法也都存在没法达成共识的状况,只是在工程实践中这种状况出现的几率很小。
那么,FLP不可能原理是否意味着研究共识算法压根没有意义?
先别这么悲观。学术界作研究,每每考虑地是数学和物理意义上最极端的情形,不少时候现实生活要美好得多(感谢这个世界如此鲁棒!)。例如,上面例子中描述的最坏情形,每次都发生的几率其实并无那么大。工程实现上多尝试几回,很大可能就成功了。
科学告诉你什么是不可能的;工程则告诉你,付出一些代价,能够把它变成可行。这就是科学和工程不一样的魅力。
那么,退一步讲,在付出一些代价的状况下,咱们在共识的达成上,能作到多好?回答这一问题的是另外一个很出名的原理:CAP原理。
提示:科学告诉你去赌场赌博从几率上总会是输钱的;工程则告诉你,若是你愿意接受最终输钱的风险,中间说不定能偶尔小赢几笔呢!网络