1、 情景分析
Alice想与Bob安排晚餐,由于他们都不愿意使用手机的“通话”功能,她发送短信建议在晚上6点见面。但是,发短信是不可靠的,Alice无法确定Bob的手机是否接受到了该消息。如果她收到来自Bob的确认消息,将会前往会面点。但Bob不能保证Alice收到了他的确认信息;如果确认信息丢失,Alice无法确定Bob是否收到她的建议,或者Bob的确认消息是否丢失。因此,Bob要求Alice发出一条确认消息,以确保她会在那里。但是这条消息也会丢失…
可以看到,如果Alice和Bob都想确定对方会来到会面点,这样的消息交换将永远持续下去。
Remark:
- 此类协议无法终止:假设存在很多需要达成共识的协议,且P是需要最少数量消息的协议之一。由于最后的确认消息可能会丢失,并且协议仍需要确认协议,我们可以简单地决定始终省略最后一条消息。这给了我们一个新的协议P0,它需要的消息少于P,与P需要最少量消息的假设相矛盾。
- Alice和Bob可以使用Paxos吗?
答:不可以,如果两个人都向服务器申请最新票号,各占据1/2的服务器,都不放弃资源,互相僵住。
2、共识
定义2.1(共识):有n个结点,其中最多有f个结点可能崩溃,即至少n-f个节点是正确的。节点i以输入值vi开始。节点必须是其中的一个值,并满足以下属性:
- 一致性 所有正确的节点决定相同的值。
- 终止 所有正确的节点在有限时间内终止。
- 有效性 决策值必须是节点的输入值。
Remark:
-
异步模型(asynchronous model)的主要特点是:
1.进程之间的通信基于消息(message)。消息的传输是可靠的,即消息可能延迟,可能乱序,但最终都会到达。
2.没有时钟(clock)可用,因此进程无法做出消息超时的判断。
3.进程的存活状态是无法检测的,即外部不能区分进程运行缓慢或是终止的情况;但是进程的运行是“诚实”的,没有“Byzantine Failures”。 -
我们假设每个节点都可以向每个其他节点发送消息,并且连接可靠,消息发出去会被接收。
-
没有广播媒体。如果节点想要向多个节点发送消息,则需要发送多个单独的消息。
-
Paxos是否同时满足三个标准?
实际上,Paxos不保证终止。例如,如果两个客户端连续请求票证,系统可能永远停留,并且他们都没有办法获得多数票。
3、不可能达成共识
3.1 FLP理论
在异步通信场景,分布式系统中只要有一个进程/节点不可用(失去响应或暂停),没有任何确定性算法能保证可用进程/节点能达成共识。(No completely asynchronous consensus protocol can tolerate even a single unannounced process death)
来源于Fischer、Lynch和Patterson三位科学家于1985年发表的论文《Impossibility of Distributed Consensus with One Faulty Process》。FLP Impossibility(FLP不可能性)是分布式领域中一个非常著名的结果,该结果在专业领域被称为“定理”,其地位之高可见一斑。该结果在2001年无悬念地被授予PODC影响力论文奖(现称为 Dijkstra奖)。
在理论情况下(严格满足一致性agreement、终止性/无锁termination、合法性/有效性validity),结果是impossible。
实际场景中,三个要求需要有所取舍(可参见CAP理论),或者使用随机算法而不使用确定性算法。
3.2 相关概念
状态树、单可能的(确定的)、双可能的/不确定的、1价等概念如下图所示。
注意:注意由于消息没有先后顺序,导致状态树的结构非常庞大,而图中只是实际状态树的简化版本。作者在证明定理时也没有描绘出完整的状态树,只是利用特殊节点找到最坏的可能从而找到了矛盾。
定义3.1 状态(configuration):我们说系统是由其状态C完全定义的(在执行期间的任何时刻)。状态包括每个节点的值,以及正在传输(已发送但尚未接收)的所有消息。
注意:状态包含两部分,节点的值和正在传输的消息。
定义3.2 单可能的/确定的:如果确定决策值与之后发生的事情无关,则我们将配置C称为单可能的/确定的。
定义3.3 双可能的/不确定的:如果节点可能决定为0或1,则配置C称为双可能的/不确定的。
注意:注意双可能的/不确定的包含两种情况(0价和1价),0价的子节点全是0价,最终决定0;1价的子节点全是1价,最终决定1。
定义3.4 传输:从状态C到后续状态Cτ的转换由事件τ=(u; m)表征,即节点u接收消息m。
注意:当m被u接收到时,C转换为Cτ。
定义3.5(状态树) 状态树是状态的有向树。 其根是状态C0,其完全由输入值V表征。 树的边缘是传输; 每个状态都具有所有适用的传输作为传出边。
3.3 证明过程
定理用反正法进行证明,先假设存在一个共识算法,通过找出矛盾来证明共识算法不存在。
定理只证明了二分输入(输入只能是0或1)的情况下,共识算法不存在。因为二分输入对于共识算法的最简单的情况,所以在更多输入的情况下,共识算法更不可能存在。
证明中首先关注初始状态:
引理3.7 如果f≥1,则存在至少一种输入值V的选择,使得相应的初始状态C0是不定的。
上面的引理将关注点放到了初始状态C为二价/不定的情况,注意f指的是不可用节点的数量。
下面插入一条引理来说明对于任意C,u1≠u2时,Cτ1τ2=Cτ2τ1。
引理3.10 假设u1≠u2的两个传输τ1=(u1; m1)和τ2=(u2; m2)都适用于C.令Cτ1τ2是通过首先应用转变τ1然后τ2而遵循C的状态,并且让Cτ2τ1为类似地定义。 它认为Cτ1τ2=Cτ2τ1。
下面的定理关注到了临界状态:
引理3.12 如果系统处于不定状态,它必须在有限时间内达到临界状态,或者它不能解决共识。
将3.7与3.12连在一起理解可得出结论:临界状态一定存在。
引理3.13 如果状态树包含临界状态,则崩溃单个节点可以创建不定叶节点; 即,崩溃阻止算法达成一致。
$\qquad$3.13的解释:对于临界节点来说,存在价不相同的Cτ1和Cτ2 ,这会使Cτ1τ2=Cτ2τ1不成立,从而使u1=u2,可证临界状态中的所有消息都被同一节点接受,如果该节点失效,则算法无法继续进行,也就无法达成共识。
前面的引理证明了临界状态一定存在,而3.13证明了临界状态会导致达不成共识。所以将这些引理组合起来就得到了FLP定理:
定理3.14 f> 0时,没有确定性算法总是在异步模型中达成共识。
4、 随机共识算法
由FLP可知,在网络可靠的前提下,任意节点失效,异步系统中不存在一个解决一致性问题的确定性算法,因此本节介绍了一个简单的解决一致性问题的随机性算法。
算法如下:
Algorithm 3.15 Randomized Consensus (Ben-Or)
1:vi ∈{0,1} ▹inputbit
2: round = 1
3: decided = false
4: Broadcast myValue(vi, round)//广播自己的值
5: while true do
Propose
6: Wait until a majority of myValue messages of current round arrived //等待接收到大于等于n/2个节点数的信息
7: if all messages contain the same value v then
8: Broadcast propose(v, round)//广播目的
9: else
10: Broadcast propose(⊥, round)//广播空
11: end if
12: if decided then
13: Broadcast myValue(vi, round+1)//广播自己的值
14: Decide for vi and terminate//该节点达成共识
15: end if
Adapt
16: Wait until a majority of propose messages of current round arrived////等待接收到大于等于n/2个节点数的信息
17: if all messages propose the same value v then
18: vi = v
19: decide = true
20: else if there is at least one proposal for v then
21: vi = v
22: else
//随机选择自己的值
23: Choose vi randomly, with Pr[vi = 0] = Pr[vi = 1] = 1/2
24: end if
25: round = round + 1
26: Broadcast myValue(vi, round)
27: end while
我们来举几个简单例子
例子中0代表今天不吃饭,1代表今天吃饭,多人协商今天是否吃饭问题。
例1.有三个节点,在通信过程时都正常无崩溃的运行。三个节点A、B、C的输入分别为0、1、1。因此C0为(011)。
第一轮:
- 对于A来说Broadcast myValue(0, 1) 随后Broadcast propose(1,1),然后执行第23行,随机选取自己的值,可能为1,或为0。若为1则达成一致,若为0,Broadcast myValue(0, 2) ,重复第一轮步骤,直到随机成1。
- 对于B来说Broadcast myValue(1, 1) 随后Broadcast propose(⊥ ,1),然后执行第21行,把自己的值改变成1,随后Broadcast myValue(1, 2) 。
- 对于C来说Broadcast myValue(1, 1) 随后Broadcast propose(⊥ ,1),然后执行第21行,把自己的值改变成1,随后Broadcast myValue(1, 2)。
例2: 有四个节点,A、B、C、D输入分别为0、0、1、1。因此C0为(0011)
第一轮:
- 对于A来说Broadcast myValue(0, 1) 随后Broadcast propose(⊥,1),然后执行第23行,随机选取自己的值,可能为1,或为0。
- 对于B来说Broadcast myValue(0, 1) 随后Broadcast propose(⊥ ,1),然后执行第23行,随机选取自己的值,可能为1,或为0。
- 对于C来说Broadcast myValue(1, 1) 随后Broadcast propose(⊥ ,1),然后执行第23行,随机选取自己的值,可能为1,或为0。
- 对于C来说Broadcast myValue(1, 1) 随后Broadcast propose(⊥ ,1),然后执行第23行,随机选取自己的值,可能为1,或为0。
可以看出算法的时间复杂度为 ,即最坏情况下。
注意:
1. 算法中第6行和第16行,需要接收到大于等于2/n的节点消息,才能正常执行下面的步骤。
2. 该算法最多能容忍f<n/2的节点崩溃。
定义3.16 只要节点集没有达成共识,即使有节点崩溃算法3.15也总会有所进展,
定义3.17 算法3.15满足共识中的有效性要求。
定义3.18 算法3.15满足共识中的一致性要求。
定理3.19 算法3.15满足共识中的终止要求,所有节点在 时间之内终止。
定理3.20 当崩溃节点f>=n/2时,在异步模型中没有共识算法能达成一致。
5、分享硬币
该算法用来改进3.15算法中第23行,加快达成共识的速度。
Algorithm 3.22 Shared Coin (code for node u)
//对于节点U ,硬币cu 以1/n的概率取0,以1-n/n的概率取1
1: Choose local coin cu = 0 with probability 1/n, else cu = 1
//节点U向所有节点广播自己的硬币cu
2: Broadcast myCoin(cu)
//等待至少n-f个节点的硬币取值,并将所有取值存储下来形成硬币集Cu
3: Wait for n − f coins and store them in the local coin set Cu
//节点U广播自己的硬币集
4: Broadcast mySet(Cu)
//等待至少n-f个节点的硬币集Cu
5: Wait for n − f coin sets
//如果在所有硬币集中某个硬币集存在一个硬币取值0,那么u节点便取输入值为0
6: if at least one coin is 0 among all coins in the coin sets then
7: return 0
8: else
//否则取1
9: return 1
10: end if
定义 3.23. u是一个节点,假设W是u从至少f+1个不同的硬币集里接收到的硬币集,那么W中至少包含f+1个不同的节点取值。
定义 3.24. 在W中所有的硬币取值都可以被所有正常运行的节点观察到
定义 3.25. 分享硬币算法3.22最多可以容忍(n/3)-1个节点崩溃
定义 3.26. 把算法3.22插入到算法3.15中,我们将可以获得一个可以在常数轮期望时间内终止,并且最多容忍(n/3)-1个节点崩溃的随机共识算法。