拜占庭将军问题(byzantine-generals-problem)是Leslie Lamport(2013年的图灵奖得主)用来为描述分布式系统一致性问题(Distributed Consensus)在论文中抽象出来一个著名的例子。
拜占庭帝国想要进攻一个强大的敌人,为此派出了10支军队去包围这个敌人。这个敌人虽不比拜占庭帝国,但也足以抵御5支常规拜占庭军队的同时袭击。这10支军队在分开包围状态下同时攻击。他们任一支军队单独进攻都毫无胜算,除非有至少6支军队(一半以上)同时袭击才能攻下敌国。他们分散在敌国的四周,依靠通信兵骑马相互通信来协商进攻意向及进攻时间。困扰这些将军的问题是,他们不确定他们中是否有叛徒,叛徒可能擅自变更进攻意向或者进攻时间。在这种状态下,拜占庭将军们如何才能保证有至少6支军队在同一时间发起进攻,从而赢取战斗?
从上面的描述中,可以看到,要想一起进攻取得胜利。需要进行克服的问题有两个:
- 消息可能丢失
- 消息可能被篡改
PS: 这里的消息可以被篡改和信息论中的信息被篡改是不一样的。在信息论中消息可以通过纠错码、校验码来对消息是否被篡改过进行验证,甚至通过纠错码来进行纠错。但是这里的被篡改是逻辑层被篡改,可以理解为是假消息,纠错码、校验码可以保证信道的质量,但是无法保证逻辑层消息被篡改。
拜占庭问题的前提
拜占庭将军问题中并不去考虑通信兵是否会被截获或无法传达信息等问题,即消息传递的信道绝无问题。(Lamport已经证明了在消息可能丢失的不可靠信道上试图通过消息传递的方式达到一致性是不可能的)。所以,在研究拜占庭将军问题的时候,已经假定了信道是没有问题的(消息可以被篡改、前后不一致,但是够保证不丢失)。
Q:这里保留一个疑问就是为啥要求消息能够保证不丢失?保证不丢失是说能够保持连接是吧。不是掉线了之后再也不能恢复了。
问题分析
先看在没有叛徒情况下,假如一个将军A提一个进攻提议(如:明日下午1点进攻,你愿意加入吗?)由通信兵通信分别告诉其他的将军,如果幸运中的幸运,他收到了其他5位将军以上的同意,发起进攻。如果不幸,其他的将军也在此时发出不同的进攻提议(如:明日下午2点、3点进攻,你愿意加入吗?),由于时间上的差异,不同的将军收到(并认可)的进攻提议可能是不一样的,这时可能出现A提议有3个支持者,B提议有4个支持者,C提议有2个支持者等等。
再加一点复杂性,在有叛徒情况下,一个叛徒会向不同的将军发出不同的进攻提议(通知A明日下午1点进攻, 通知B明日下午2点进攻等等),一个叛徒也会可能同意多个进攻提议(即同意下午1点进攻,又同意下午2点进攻)。
叛徒发送前后不一致的进攻提议,被称为“拜占庭错误”,而能够处理拜占庭错误的这种容错性称为「Byzantine fault tolerance」,简称为BFT。
消息不能丢失,可能被篡改,可以利用“工作量证明” 来解决这个问题。
消息可能丢失,不可以被篡改,可以利用Paxos、Raft等算法来达成最终一致性。