【虾说区块链】分布式系统共识的FLP不可能原理与CAP猜想

欢迎收听「虾说区块链」。现在区块链这个概念在互联网上相当火热,这里简单做一个普及,不涉及项目推广投资,单纯地对区块链相关基础知识概念作一个说明讲解。本人区块链技术爱好者,结合相关区块链资料总结整理了「虾说区块链」,也是自己一个学习笔记,涉及相关内容如理解有误,也请及时指正。

1

共识机制基础概念

首先,共识机制在分布式系统中是无解的,为什么说是无解,众多的节点之间通信,必然存在网络自身不可靠的原因、主机故障原因、恶意操控等原因,故是无法保证实现完全的共识,这里不是笔者随便下的结论,Fischer, Lynch 和 Patterson三位在1985年就提出了一个FLP不可能原理:在网络可靠的前提下,任意节点失效,一个或者多个的最小化异步模型系统中,不可能存在一个解决一致性问题的确定性算法。这三位的论文后来获得了Dijkstra奖。这一理论已被可靠的论证过,所以不用再花大力气在异步分布式系统中去设计一个完全一致的共识算法。(这里不深究FLP原理,有兴趣可以百度Lynch的)

FLP说明在异步分布式系统中完全一致性是不可能的,但这是一个科学理论,应用到现实工程中,我们可以牺牲一些代价把不可能变成可能,这就是科学和工程的最大区别,就像你炒股吧,官方肯定会告诉你股市有风险,入市需谨慎,但你肯定认为在你高超的操作下还是能赚钱的。那在计算机工程领域中2000年 Eric Brewer在ACM 研讨会提出猜想,CAP猜想,CAP拆解后就是一致性(Consistency)所有节点上的数据时刻保持同步、可用性(Availablity)每个请求都能接受到一个响应不论响应成功或失败、分区容忍性(Partition)系统内部有消息失效的情况下仍能提供持续服务。

实际运用在工程环境下,适当取舍这三者,一致性、可用性和分区容错性三者无法在分布式系统中被同时满足,并且最多只能满足其中两个。这样就出现了以下三种情况:

1)CA without P:如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。Zookeeper为此类设计。

2)CP without A:如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。MongoDB、Redis为此类设计。

3)AP wihtout C:要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。CouchDB、cassandra为此类设计。

CAP猜想出现至今都一直存在很多质疑,有人提出概念的混乱、不适应数据库事务架构等各种质疑,2002年对CAP猜想被证实为一个定理,证明了CAP三者不可能同时满足,但没有证明任意两者都可满足,对C\A\P作了更明确的声明:

(论文原文:http://lpd.epfl.ch/sgilbert/pubs/BrewersConjecture-SigAct.pdf),

最初这个辩证是在webserver集群环境下的。

1)C:一致性被称为原子对象,任何的读写都应该看起来是“原子“的,或串行的。写后面的读一定能读到前面写的内容。所有的读写请求都好像被全局排序。

2)A:对任何非失败节点都应该在有限时间内给出请求的回应。(请求的可终止性)

3)P:允许节点之间丢失任意多的消息,当网络分区发生时,节点之间的消息可能会完全丢失。

质疑一直存在。2012年lynch重写论文,再次对CAP做了进一步的解释:

把CAP理论的证明局限在原子读写的场景,并申明不支持数据库事务之类的场景。

一致性场景不会引入用户agent,只是发生在后台集群之内。

把分区容错归结为一个对网络环境的陈述,而非之前一个独立条件。这实际上就是更加明确了概念。

引入了活性(liveness)和安全属性(safety),在一个更抽象的概念下研究分布式系统,并认为CAP是活性与安全熟悉之间权衡的一个特例。其中的一致性属于liveness,可用性属于safety。

把CAP的研究推到一个更广阔的空间:网络存在同步、部分同步;一致性性的结果也从仅存在一个到存在N个(部分一致),引入了通信周期round,并引用了其他论文,给出了为了保证N个一致性结果,至少需要通信的round数。

(论文原文:http://groups.csail.mit.edu/tds/papers/Gilbert/Brewer2.pdf)

谈论了以上CAP原理,目的就是为了说明共识机制是相对的,目前没有一种决对完美的共识机制,所有各种共识机制都是理论结合工程实践产生的。

2

拜占庭问题

拜占庭将军问题就会时常看到,拜占庭将军问题是一个协议问题,拜占庭帝国军队的将军们必须全体一致的决定是否攻击某一支敌军。问题是这些将军在地理上是分隔开来的,并且将军中存在叛徒。叛徒可以任意行动以达到以下目标:欺骗某些将军采取进攻行动;促成一个不是所有将军都同意的决定,如当将军们不希望进攻时促成进攻行动;或者迷惑某些将军,使他们无法做出决定。如果叛徒达到了这些目的之一,则任何攻击行动的结果都是注定要失败的,只有完全达成一致的努力才能获得胜利(来自百度百科)。

这里不讨论军事问题,把拜占庭将军问题引入到计算机领域,在分布式系统中,网络中各节点由于硬件设备故障、网络延时或故障、恶意攻击导致整个系统中出现不可预知的错误。把拜占庭将军问题嵌入到分布式系统中说明:

前提:

1.网络中各节点信道可靠。

2.网络中节点数可知为n。

分布式网络中的众多节点,同时更新或者删除数据,必须达到共识的状态,但是有些节点会出现不确定故障或者恶意篡改,导致分布式节点数据不一致,这个问题现实中是不可避免的。那么要求系统能正常运行,这里引入一个容错的概念,可以在不完全一致的状态下,系统仍然可以正常运行。

所谓的正常运行有两种概念:

  1. 数据的正常更新后提供服务。

  2. 由于故障节点过多数据不更新提供服务,再发起一次共识。

如何来定义这个正常运行,这个需要有一个取舍,因为结合实际应用很多因素需要考虑,理论的严谨和工程的取舍这个一般都会有权衡。下面说明通过容错达成的正常运行。

设置一个变量x,节点数为n,假设其中一个节点为i。通过各种条件设置应用场景:

节点i发布请求x,诚实节点收到的是(x1、x2...xi...xn)集合,这些集合内x值一致,那么从i的诚实性考虑,有可能i是诚实节点、也有可能i本身就还是恶意节点。

i节点是诚实节点,那么其他诚实节点也同样发送x值。

结合1.2,我们不管i节点的诚实性,所有诚实节点都收到一样的x值集合。

这样网络中节点收到的请求更新一致,如果i是诚实节点,那么保证了正常运行。这种情况将1.2结合系统达到了一致性和正常运行的两个要求。

但是这是理想化的状态在现实网络节点中刚才的假设都是理想化的。通过执行流程来看下:

再假设三个前提:1.x发送都可正确传达到其余节点中。2.接收节点知道发送节点。3.节点知道x消息完整。

那么网络中n个节点,恶意节点为m个,那么n>3m+1。

i发送x给每一个节点,每个节点收到x则更新、未收到默认就为不操作。

每个节点收到i发送x更新后,恶意节点m发送y其余节点,发送是一个递归过程。

每个节点收集i发送x信息,恶意节点m接收x值,不发送至其余剩余节点。

下面通过图形说明:

这里n=3,m=1,那么节点i和节点B是诚实节点,但是B节点不知道应该是x还是y是更新。再引入一个节点:

这种情况下i、b、c节点是诚实节点,x值在b、c集合中出现2次,y出现一次,故达到了共识。这个前提是i是诚实节点,如果i本身就不是诚实节点,i发送不同三个值,那整个系统无法共识。

n >3m+1 m=2 n=7

这个过程就会比较复杂了,假设a和d是恶意节点,那么每个诚实节点通过递归方式去接受其余节点的信息,然后收集的到信息集合中通过多数原则来确定。

b 、c、e、f为诚实节点加上i,系统达成共识。当然i如果是恶意节点,发送不同消息给下面节点,那么共识将无法成立,但是如果i发送是有一半是x值一半是不同值,可以推理下。以上推理过程在拜占庭将军问题中称为口头协议。追溯我们之前写的三个假设中,如果接收者知道发送者,那么就有书面协议。下面对书面协议再作说明:

所谓书面协议,就是网络节点在传输过程中添加一个签名,任何节点可以验证签名可靠性。

还是用节点收到的数据集合v,i节点发送x值给各个节点,节点收到v(x),然后发送v(x):i给其余节点,如果收到的一串值中没有v(x),那么就把这个值添加到自己的v集合中。每个节点收到值后,通过choice函数判断。在口头协议中三个节点当i节点发送不同值的时候无法一致,那么这里加上签名后可以看下,以图说明:

这种情况下最后a、b节点接收信息后都是x、y那么在系统中两个节点信息一致。这就解决了3节点口头协议不能完成一致的问题。如果n=4,m=2有兴趣可以再推理一次,结果也是一致的。

综上所述,在拜占庭问题中n>3m+1能得到保证,拜占庭将军问题比较考验整个推理,笔者也是根据自己理解写了点介绍,有不对的请及时指正。

(音频内容来源:“投河自尽的鱼”)

以下是我们的社区介绍,欢迎各种合作、交流、学习:)

点击“阅读原文”进入直播室听专栏音频

阅读原文

你可能感兴趣的:(【虾说区块链】分布式系统共识的FLP不可能原理与CAP猜想)