背景
在常见的分布式系统中,总会发生诸如机器宕机或网络异常(包括网络消息的延迟、丢失、重复、乱序,还有网络分区)等情况。Paxos算法需要解决的问题就是如何在一个可能发生上述异常的分布式系统中,快速且正确地在集群内部对某个状态(日志、数据、命令等)的值达成一致,并且保证不论发生以上任何异常,都不会破坏整个系统的一致性。
一、拜占庭将军问题
拜占庭将军问题提供了对分布式共识问题的一种情境化描述。
是分布式系统领域最复杂的容错模型,他描述如何在存在恶意行为(消息篡改或者伪造)的情况下使分布式系统达成一致,是我们理解分布式一致性协议和算法的重要基础。参考:https://zhuanlan.zhihu.com/p/107439021
分析
将军数量可以任意,假如有将军数量为三,分布在不同的地方,他们之间可以两两通过消息互相通信,目的:最终达成一致进攻或者撤退的共识。
(1)如果三个将军都是忠诚的(对于某个将军发送给其他将军的消息总是一致的),那么最终都会达成一致进攻或者撤退的共识。
(2)如果三个将军存在一个敌将,敌将会散布虚假的进攻、撤退消息,目的:为了就是破坏共识。
- 以0和1表示撤退、进攻的消息。
- 以组合**(out:发出,in:收到)**表示某个将军发出、收到消息的状态。那么对于某个将军某次的协商状态:(0,0)、(0,1)、(1,0)、(1,1)
- 以A、B、C表示三位将军
下图以C为叛将为例,C干扰A发送进攻信号,导致将军A单独进攻。
其实总共有6种协商不一致的情况,对于叛军可能是A、B、C任一个,因此共三种情况。
而对于将军A、B不一致的情况为A(0,1) and B(1,0) 、A(1,0) and B(0,1)。
ps:如果将军A、B总是一致的,那么无论叛军C如何干扰都没用。
推论
假定总共存在m位叛将,那么至少总将领数为 3m + 1,那么最终总能达成一致的行动计划。
值的注意的是, 在这个算法中, 叛将人数_m_是已知的, 且叛将人数_m_决定了迭代递归的次数(按照叛将拆分小组,保证每个小组内一个叛将)
即叛将数_m_决定了进行作战信息协商的轮数, 如果存在_m_个叛将, 则需要进行_m+1_轮作战信息协商. 这也是上述存在1个叛将时需要进行两轮作战信息协商的原因.
解决方案
Leslie Lamport在论文中给出了两种拜占庭将军问题的解决方案, 也就是证明3m + 1的问题,即对于二忠一叛的条件下,想要总是达到一致性是不可能的。
- 口信消息型解决方案(A solution with oral message)
- 签名消息型解决方案(A solution with signed message).
1、口信型解决方案
口信消息规定
- 任何已经发送的消息都将被正确传达
- 消息的接收者知道是谁发送了消息
- 消息的缺席可以被检测
通过规定可得知,口信消息不能篡改但是可以被伪造,由拜占庭问题的3m+1得出,可以以3忠1叛推导,首先发送消息的为指挥官,其余为副官,需要做两轮协商,没收到作战消息就撤退。
2、签名型解决方案
简言之就是忠将具有识别消息是否被篡改的能力,根据虚假信息找出叛将军。
在口信消息定义的基础上增加定义
- 忠诚将军的签名无法伪造,消息无法被篡改和伪造(口信消息定义是消息不能篡改但是可以被伪造)
- 任何人都能验证将军签名的真伪
还是以三将军为例,三个将军2个忠一个叛
同样可以类比多忠多叛的情况。
在消息篡改能被发现的条件下
- 如果莫将发出不一致的消息,直接被判别为叛将
- 如果某将发出消息一致,那么就证明是忠将,如果收到其他将军转发的消息和自己收到的不一致,那么就找出了叛将
因此,签名消息型解决方案可以处理任何数量叛将的场景,因为三个一小组在消息不能篡改的前提下,总能找出叛将。
总结
拜占庭将军问题提供了对分布式共识问题的一种情景化描述,为理解和分类现有众多分布式一致性协议和算法提供了框架,现有的分布式一致性算法主要分为两类
- 一类是故障容错算法:即非拜占庭算法,解决的是分布式系统存在故障但是不存在被恶意攻击的场景下的共识问题,主要针对消息丢失、重复等问题,面对消息被篡改就无力了,一般用于局域网场景下的分布式算法,如Paxos、Raft、ZAB协议等。
- 一类是拜占庭算法:既可以解决分布式系统故障,又可解决恶意攻击的问题,如在数字货币的区块链技术中,属于此类算法有PBFT、PoW算法。
二、Paxos算法
参考:https://www.cnblogs.com/linbingdong/p/6253479.html
目的就是保证所有分布式节点(进程)上面某各状态(值)的一致性。具体就是通过协商保证只有一个value会被选定,当value被选定后,分布式节点(进程)最终也能获取到被选定的value。
// TODO
三、Raft算法
参考:https://cloud.tencent.com/developer/article/1525566
Raft是用于管理复制日志的一致性算法。它的效果相当于(multi-)Paxos,跟Paxos一样高效,但结构与Paxos不同。这使得Raft比Paxos更容易理解,也为构建实用系统提供了更好的基础。
// TODO