Leslie Lamport在其论文中描述了如下问题:
一组拜占庭将军分别各率领一支军队共同围困一座城市。为了简化问题,将各支军队的行动策略限定为进攻或撤离两种。因为部分军队进攻部分军队撤离可能会造成灾难性后果,因此各位将军必须通过投票来达成一致策略,即所有军队一起进攻或所有军队一起撤离。因为各位将军分处城市不同方向,他们只能通过信使互相联系。在投票过程中每位将军都将自己投票给进攻还是撤退的信息通过信使分别通知其他所有将军,这样一来每位将军根据自己的投票和其他所有将军送来的信息就可以知道共同的投票结果而决定行动策略。
系统的问题在于,可能将军中出现叛徒,他们不仅可能向较为糟糕的策略投票,还可能选择性地发送投票信息。假设有9位将军投票,其中1名叛徒。8名忠诚的将军中出现了4人投进攻,4人投撤离的情况。这时候叛徒可能故意给4名投进攻的将领送信表示投票进攻,而给4名投撤离的将领送信表示投撤离。这样一来在4名投进攻的将领看来,投票结果是5人投进攻,从而发起进攻;而在4名投撤离的将军看来则是5人投撤离。这样各支军队的一致协同就遭到了破坏。
虽然通过引入了一个故事可以增加故事的吸引力,再加上拜占庭这个描述反而更使人头大。仅仅通过文本分析,可以提出很多文中并没有给出的消息。 比如,9个将军,每个将军都要给其它8个将军投票吗?为什么会引入忠臣和叛徒这样的字眼?忠臣的将军和叛徒的将军判断依据是什么?而且,每个将军在发出投票的时候, 是不是事先已经知道其它所有将军的意图了呢?如果不能提前知道其它将军的决定,怎么做出忠臣和叛徒这样的表述呢?判断依据是什么?
“假设有9位将军投票,其中1名叛徒。8名忠诚的将军中出现了4人投进攻,4人投撤离的情况。” 这个表述很奇怪,投票还没完成,结果还没出来,事前不应该描述他们是忠臣还是叛徒。 只有在知道全局,且假设其它将军没有叛徒的时候,才能做出叛徒的行为。这里隐藏了2个前提条件:
- 知道其它所有将军的决定。
- 确保其它将军的决定都没有被篡改。
也就是说必须具备这2个条件,才能保证做出“叛徒”的行为,否则无法实现判断究竟是不是“叛徒”。
这里的辩解似乎过于咬文嚼字而忽视了重心,真正应该关心的问题难道不应该是如何在即便存在叛徒的情况下,如何保证系统意见的有效性吗?————也就是让系统达成共识。 除了所谓的叛徒行为会影响系统最终结果外,信史会不会中途修改决定? 或者干脆送不到其它将军手里?
英文版中说,如果loyal的将军数目是disloyal的3倍,那么就可以实现 Byzantine fault tolerance
Byzantine fault tolerance can be achieved if the number of loyal (non-faulty) generals is greater than three times the number of disloyal (faulty) generals. There can be a default vote value given to missing messages. For example, missing messages can be given a "null" value. Further, if the agreement is that the null votes are in the majority, a pre-assigned default strategy can be used (e.g., retreat).
解决方案
第一招:少数服从多数
要是奸细少,咱们就投票,听大多数人的。比如三个将军,只有一个是奸细,那两个忠诚的将军就能做出正确的决定。但这招有个问题,奸细要是超过三分之一,就不灵了。
第二招:盖章签字
就像以前签合同要盖章一样,每个将军发的消息都要有独特的“签名”,这样就知道消息是不是真的了。现在用的是一种叫“数字签名”的技术,就像高级的电子印章,很难伪造。但这招也有缺点,成本高,而且不适合那些对安全要求极高的系统。
第三招:查验口令
就像以前军队里用的暗号一样,在消息里加上特殊的“口令”,用来检查消息有没有被篡改。这招比“签名”便宜,但也不能完全保证安全。
拜占庭容错
容错就容错,为什么前面要加一个”拜占庭容错”的定语呢?原来拜占庭容错只是说, 系统达成共识的方式是大多数人的意见是统一的,至于意见本身对不对,这个错,拜占庭容不了。
“拜占庭容错”啊,它就像咱们村里开大会,要保证大家听到的消息是一样的。如果村长要宣布一件重要的事,比如明天要不要开仓放粮,他得告诉村里的每个人。这个“拜占庭容错”啊,就是保证不管村长用什么方法通知,是敲锣打鼓,还是派人挨家挨户说,最后每个人听到的结果都得一样,要么都说要开仓,要么都说不开仓。
但是啊,这个“拜占庭容错”只管大家听到的消息一样不一样,不管消息本身对不对。
比如说,村长要是故意说谎,说明天要打仗了,大家都要躲起来。他把这个谎话传给了每个人,每个人听到的都是一样的,那这个“拜占庭容错”就觉得没问题了,因为它只管消息一致,不管消息真假。