拜占庭将军问题
作者:互联网
拜占庭将军问题其实是借拜占庭将军的故事展现了分布式共识问题
故事大概是这么说的:
拜占庭帝国即中世纪的土耳其,拥有巨大的财富,周围10个邻邦垂诞已久,但拜占庭高墙耸立,固若金汤,没有一个单独的邻邦能够成功入侵。任何单个邻邦入侵的都会失败,同时也有可能自身被其他9个邻邦入侵。拜占庭帝国防御能力如此之强,至少要有十个邻邦中的一半以上同时进攻,才有可能攻破
然而,如果其中的一个或者几个邻邦本身答应好一起进攻,但实际过程出现背叛,那么入侵者可能都会被歼灭
于是每一方都小心行事,不敢轻易相信邻国。这就是拜占庭将军问题
在拜占庭问题里,各邻国最重要的事情是:所有将军如何能过达成共识去攻打拜占庭帝国
达成共识并非坐下来开个会那么简单,有的将军心机深不可测,口是心非,如果有叛徒,可能会出现各种问题:
- 叛徒可能欺骗某些将军自己将采取进攻行动
- 叛徒可能怂恿其他将军行动
- 叛徒可能迷惑其他将军,使他们接受不一致的信息,从而感到迷惑
1、二忠一叛的难题
假设有A、B、C三位将军,只有半数以上的将军参与进攻,才能击败敌人,在这个期间,将军们彼此之间需要通过信使传递消息,然后协商一致之后,才能在同一时间点发动进攻
举个例子,有一天,三位将军讨论明天是进攻还是撤退,并让信使传递消息,按照少数服从多数的原则投票表决,两个人意见一致就可以了,比如:
- A根据侦查情况决定撤退
- B和C根据侦查情况,决定进攻
按照原则,A也会进攻。最终,3支军队同时进攻,大败敌军
一旦有人在暗通敌军,就会出现作战计划不一致的情况。比如A向B、C撤退的消息,B向A、C发送了进攻的消息。撤退:进攻=1:1,无论C投进攻还是撤退,都会成为2:1,这个时候还是会形成一个一致的作战方案
但是,如果C是叛徒,让信使向A发送了撤退,向B发送了进攻,那么:
- A看到的是撤退:进攻=2:1
- B看到的是撤退:进攻=1:2
按照少数服从多数的原则,就会出现A单独进攻,最后会因为寡不敌众,被敌军击败
叛将C通过发送误导消息,干扰了A和B的作战计划,导致这两位忠诚的将军被敌军逐一击败。这就是所说的二忠一叛难题
2、口信消息型拜占庭问题之解
三位将军都分拨一部分军队,由D率领,D参与作战计划并执行作战指令。这样,3位将军的作战讨论变为了4位将军的作战讨论,这能够增加讨论中忠诚将军的数量
而且,4位将军还约定了,如果没有收到命令,就执行预设的默认命令,比如撤退。除此之外,还约定了一些流程来发送作战消息、执行作战指令,比如,进行两轮作战信息协商
第一轮:
- 先发送作战信息的将军作为指挥官,其他的将军作为副官
- 指挥官将他的作战信息发送给每位副官
- 每位副官将从指挥官处收到的作战信息,作为他的作战指令;如果没有收到作战信息,将把默认的撤退作为指令作战
第二轮:
- 除了第一轮的指挥官外,剩余的3位将军分别作为指挥官,向另外2位将军发送作战信息
- 然后,这3位将军按照少数服从多数执行收到的作战指令
1)假设第一轮是忠诚的D先发送作战信息,作战指令是进攻
在第二轮作战信息协商中,A、B、C分别作为指挥官,向另外2位发送作战信息进攻,因为C已经叛变了,所以,为了干扰作战计划,他就对着干,发送撤退作战指令
最终,A和B收到的作战信息都是进攻、进攻、撤退,按照原则,A、B、D一起执行作战指令进攻,实现了作战计划的一致性,保证了作战的胜利
2)如果是叛徒C先发送作战信息,干扰作战计划,结果会有所不同吗?
第一轮,C向D发送作战指令进攻,向A、B发送作战指令撤退
然后,在第二轮作战信息协商中,A、B、D分别作为指挥官,向另外两位发送作战信息
最终,A、B、D收到的作战信息都是撤退、撤退、进攻,按照原则,A、B、D一起执行作战指令撤退,实现了作战计划的一致性。也就是说,无论叛将如何捣乱,A、B、D都执行一致的作战计划,保证作战的胜利
这个解决办法,其实是兰伯特在论文中提到的口信消息型拜占庭问题之解:如果叛将人数为m,将军人数不能少于3m+1,那么拜占庭将军问题就能解决了
这个算法有个前提,也就是叛将人数m,或者说能容忍的叛将数是m,是已知的。在这个算法中,叛将数m决定递归循环的次数(也就是说,叛将数m决定将军们要进行多少轮作战信息协商),即m+1轮(如果只有C叛变,那么就进行了两轮)
3、签名消息型拜占庭问题之解
可以通过签名的方式,在不增加将军人数的情况下,解决二忠一叛的难题。首先通过签名实现这样几个特性:
- 忠诚将军的签名无法伪造,而且对他签名消息的内容进行任何更改都会被发现
- 任何人都能验证将军签名的真伪
如果忠诚的将军B先发起作战消息协商,一旦叛将C修改或伪造收到的作战信息, 那么A在收到C的作战信息的时候,会发现B的作战信息被修改,C已经叛变,这时将忽略来自C的作战信息,最终执行B发送的作战信息
如果叛变将军C先发送误导的作战信息,那么,A和B按照一定规则(比如取中间的指令)在排序后的所有已接收到的指令中(比如撤退、进攻)中选取一个指令,进行执行,最终执行一致的作战计划
通过签名机制约束叛将的叛变行为,任何叛变行为都会被发现,也就会实现无论有多少忠诚的将军和多少叛将,忠诚的将军们总能达成一致的作战计划
4、小结
拜占庭将军问题描述的是最困难的,也是最复杂的一种分布式故障场景,除了存在故障行为,还存在恶意行为的一个场景。在存在恶意节点行为的场景中(比如在数字货币的区块链技术中)必须使用拜占庭容错算法
而在计算机分布式系统中,最常用的是非拜占庭容错算法,即故障容错算法(Crash Fault Tolerance,CFT)。CFT解决的是分布式的系统中存在故障,但不存在恶意节点的场景下的共识问题。也就是说,这个场景可能会丢失消息,或者有消息重复,但不存在错误消息,或者伪造消息的情况、常见的算法有Paxos算法、Raft算法、ZAB协议等
参考:
01 | 拜占庭将军问题:有叛徒的情况下,如何才能达成共识?
标签:发送,进攻,将军,撤退,问题,拜占庭,作战 来源: https://blog.csdn.net/qq_40378034/article/details/117627128