「分布式系列」拜占庭将军问题

简介: 拜占庭将军问题介绍

拜占庭概述


首先来说说,什么是拜占庭


网络异常,图片无法展示
|


拜占庭即拜占庭帝国,又称东罗马帝国,首都位于如今土耳其的伊斯坦布尔。如上图可以看到,当时的拜占庭帝国国土辽阔,横跨亚、欧、非大陆,环抱地中海。


拜占庭将军问题


网络异常,图片无法展示
|

在那个冷兵器时代,为了征服与反征服,在如此辽阔的疆域不同地方经常驻守着由成百上千个将军领导的军队,如上图。


  • 拜占庭帝国的军队要面临的现实问题是,如何在广阔的疆域内实现所有军队的统一调度、消息交互。在那个冷兵器时代,消息指令的传递只能依靠通信士兵人为进行传递。
  • 而因此正由于是人为传递消息,若通信士兵在传递途中因暴病、天气、地理等各种原因没有及时传递消息,再或者进行了叛变,故意不将消息传递或将统一发号的命令进行虚假篡改,那么将军们得到的指令会大相径庭,行动得不到统一保证,因此传递消息的信道是不可靠的,因此导致出现行动执行的一致性问题。


综上,便是拜占庭将军问题


拜占庭将军问题,实质上是一致性问题,是不同个体(将军)之间在分布式环境(辽阔疆域)中通过不可靠信道(通信士兵)接收消息(命令)后采取一致性行动的问题。


分布式领域中“拜占庭将军问题”


网络异常,图片无法展示
|


拜占庭将军问题,其实是一个现实存在的共性问题,只要场景和条件成立便可以认为它是某个领域的拜占庭将军问题,是一个广泛问题的现实子集而已。


我们把这个问题延伸到计算机和互联网领域的话,分布式已经是互联网中常见的服务部署方案,由于硬件错误、网络拥塞或断开以及遭到恶意攻击,计算机和网络可能出现不可预料的行为,这和拜占庭将军问题产生场景和条件是相仿的。


据此,莱斯利·兰伯特(Leslie Lamport)等提出了著名的拜占庭将军问题(Byzantine Failures) 来论述分布式环境下点对点通信时在存在消息丢失的不可靠信道上试图通过消息传递的方式达到一致性是较为困难的。


莱斯利·兰伯特(Leslie Lamport)也是著名的Paxos一致性算法的作者,关于本系列分布式介绍后续的Raft一致性算法也是在改进Paxos的初衷进行设计的,这里简单了解下概念相关性线索轨迹,感兴趣可以继续阅读本篇后续文章。


这里将现实场景的拜占庭帝国分布式服务做下对比,如下:

场景

信源

信道

消息

不可靠原因

拜占庭帝国

中央 <----> 将军
将军 <----> 将军

通信士兵

命令

天气、地理、战争、叛变

分布式服务

服务节点 <----> 服务节点

网络

报文

损毁、超时、中断、恶意攻击


问题核心剖析


问题核心


分布式环境/服务中拜占庭将军问题要解决的核心问题是:如何在缺少可信任的中央节点和可信任的通道的情况下,分布在网络中的各个节点应如何达成共识的一致性问题。 这是分布式服务中首要解决的议题,它也是其他所有问题的基础和根本保证。


问题分析


网络异常,图片无法展示
|

这里尝试剖析问题本质需要从现象到本质一层层剖析根源,这里个人认为是首先有 分布式环境 的客观现实导致服务集群的 节点分散 ,当我们充分利用和享受分布式带来的优势后也需要面临和解决海量节点个体统一协调、指挥的 一致性问题 ,而无论是让统一的控制中心下发指令还是让节点之间互相协商都必须经历 消息交互 才能实现通信彼此了解对方和外部环境的最新状态信息,而承载交互的可能的最小承载因子是 信息 ,因此我们试着从根源开始剖析!


网络异常,图片无法展示
|


根据克劳德·艾尔伍德·香农(Claude Elwood Shannon)提出的信息论,我们一般将信息分为信源、信宿、信道三部分,信息体作为载体通过信道穿梭在信源信宿之间。


下面我们基于以上概念将其引申到分布式环境下,每个服务节点在发送消息时便是信源角色,若是接收消息则是信宿角色,信道是建立在节点之前双向的通道。

网络异常,图片无法展示
|

构成

角色定位

作用

可能存在问题

信源

通信发起者

产生信息体

无法溯源、异常

信宿

通信接收者

接收信息体

伪造、异常

信道

通信通道

传递信息体

被劫持、被监听、中断

信息体

通信载体

装载信息体

篡改、丢失


因此,我们剖析该问题呈现特点是节点不可靠性通道不可靠性信息不可靠性,因此要针对这些问题特点来进行针对性解决,从而确保一致性的达成。


问题解决


解决方案:口头协议


实现过程


网络异常,图片无法展示
|

口头协议 ,又称为 口信消息(Oral message) 。满足以下三个条件的方式称为 口头协议


  • 每个被发送的消息都能够被正确的投递(信道绝对可信)
  • 信息接收者知道是谁发送的消息(消息来源可知,但不知道上一个消息来源,即不可溯源)
  • 能够知道缺少的消息


该方案的实现方式是:


  • [STEP-1] 各个节点接收Commander指令Command-1
  • [STEP-2] 每个节点收到Commander消息后,再将该消息分发到其他节点上,最终每个节点都会收到其他节点发来的消息集合{Commander消息、其他节点传递的Commander消息},根据消息集合来判断下一步如何执行。

节点

收到的消息集合

A

{ CommandCommander发送、CommandB传递、CommandC传递 }

B

{ CommandCommander发送、CommandA传递、CommandC传递 }

C

{ CommandCommander发送、CommandA传递、CommandB传递 }


不可靠场景


Commander不可靠


网络异常,图片无法展示
|

Commander 不可靠时,各节点收到信息集合为

节点

收到的消息集合

决策判断

节点执行结果

分布式一致性

A

{ command-0Commander发送、command-1B传递、command-1C传递 }

指令不一致

不执行

一致

B

{ command-1Commander发送、 command-0A传递、command-1C传递 }

指令不一致

不执行

一致

C

{ command-1Commander发送、 command-0A传递、command-1B传递 }

指令不一致

不执行

一致


Node不可靠


少数不可靠


网络异常,图片无法展示
|

少数节点不可靠场景 ,当 A 不可靠时,各节点收到信息集合为

节点

收到的消息集合

决策判断

节点执行结果

分布式一致性

A

{ command-1Commander发送、command-1B传递、command-1C传递 }

不可靠节点

执行伪造命令command-0

多数一致

B

{ command-1Commander发送、 command-0A传递、command-1C传递 }

指令不一致

不执行

多数一致

C

{ command-1Commander发送、 command-0A传递、command-1B传递 }

指令不一致

不执行

多数一致


多数不可靠


网络异常,图片无法展示
|

多数节点不可靠场景 ,当 A、C 不可靠时,各节点收到信息集合为

节点

收到的消息集合

决策判断

节点执行结果

分布式一致性

A

{ command-1Commander发送、command-1B传递、command-0C传递 }

不可靠节点

执行伪造命令command-0

多数不一致

B

{ command-1Commander发送、 command-0A传递、command-0C传递 }

指令不一致

不执行

多数不一致

C

{ command-1Commander发送、 command-0A传递、command-1B传递 }

不可靠节点

执行伪造命令command-0

多数不一致


综上,我们可以看到,无论是发号施令的Commander,还是执行命令的Node节点,当不可靠节点数量较多时,分布式中的一致性将遭受破坏,无法保证。
确保一致性情况下,不可靠节点与总结点数量关系

n代表所有节点(含Commander、Node)总数,m代表不可靠节点数量,则他们必须满足n≧3m+1这样的数量关系方可保证分布式的一致性,感兴趣可以自己推导下,以下是样例:

节点总数(n)

Commander数量(1)

Node数量(n-1)

不可靠最大节点数(m)

4

1

3

1

7

1

6

2

10

1

9

3

...

...

...

...


不足


  • 消息无法溯源,无法确定其他节点传递消息的正确性
  • 当不可靠节点大多数存在的情况下,无法达成一致性


解决方案:书面协议


为了进一步解决口头协议的不足,改进点如下:


  • 为了确保其他节点传递消息的正确性可溯源,让节点通信都增加签名信息
  • 当不可靠节点大多数存在时无法达成一致性,但这是一个未知数,无法实现按照推演公式安排节点总数量来保证容错,而消息传递加签名信息的方式能很好的确保消息传递的可溯源、准确性,以此可以解决任意不可靠节点存在的场景


实现过程


网络异常,图片无法展示
|

书面协议 ,又称为 签名协议 。该方案的实现方式是:


  • [STEP-1] 各个节点接收Commander带有签名的指令Command-1
  • [STEP-2] 每个节点收到Commander消息后,将该消息进行签名后再分发到其他节点上,最终每个节点都会收到其他节点发来的带有签名信息的消息集合{Commander签名消息、其他节点签名的Commander消息},根据消息集合来判断下一步如何执行。

节点

收到的消息集合(均带有签名信息)

A

{ CommandCommander签名、CommandB签名、CommandC签名 }

B

{ CommandCommander签名、CommandA签名、CommandC签名 }

C

{ CommandCommander签名、CommandA签名、CommandB签名 }


特点


基于口头协议的特点,签名协议规定,每条消息只可以复制,然后加上自己的签名再发给其他节点,增加如下特点:


  • [1] 节点签名是不能伪造的,内容修改可检测
  • [2] 任何节点都可以识别Commander的签名,不可靠节点可以伪造Commander的签名


不足


  • 尽管消息传递均被签名,但是发送者不一定可信,有可能是A节点使用了C节点签名来通知B节点,因此需要一个中心化的签名管理规则或机构对各个发送者进行核验方可确认真实性


书面协议的本质就是引入了签名机制,这使得所有消息都可追本溯源。化解了口头协议中1/3要求,只要采用了书面协议,可靠节点就可以达到一致。


解决方案:工作量证明


工作量证明算法(PoW算法,Proof of Work) 广泛应用于存在恶意攻击和篡改且不可靠的分布式环境下,应该广泛的是区块链技术


中本聪在比特币白皮书中,通过比特币协议给出了终极解决方案如下:


  • 引入工作量证明机制,只有第一个完成规定计算工作的节点才能传播信息,从而保证一段时间内只有一个提案。
  • 引入非对称加密算法,为信息传递提供签名技术支持,以保证消息传递的私密性,且不可抵赖、不可篡改。


关于该部分方案的实现在后续章节中单独论述。


拜占庭将军问题是由莱斯利·兰伯特(Leslie Lamport)等提出的,但真正解决这一难题的是中本聪

兰伯特提出的Paxos算法,还有后续改进的Raft算法、Zab协议都是基于可靠信道环境下消息不会被篡改和伪造等恶意攻击的前提下实现的分布式一致性协议,面对不可靠信道等存在恶意篡改风险的分布式环境是无法保证一致性的。


总结


拜占庭将军问题,不关心结果的对与错,只关心节点执行的一致性问题。

网络异常,图片无法展示
|

现有的 分布式一致性协议和算法 主要可分为两类:


  • 非拜占庭容错算法
    非容错算法(Crash Fault Tolerance, CFT),解决的是分布式系统中存在故障,但不存在恶意攻击的场景下的共识问题。也就是说,在该场景下可能存在消息丢失,消息重复,但不存在消息被篡改或伪造的场景。一般用于局域网场景下的分布式系统,如分布式数据库。属于此类的常见算法有Paxos算法、Raft算法,、Zab协议等。
  • 拜占庭容错算法
    可以解决分布式系统中既存在故障,又存在恶意攻击场景下的共识问题。一般用于互联网场景下的分布式系统,如在数字货币的区块链技术中。属于此类的常见算法有PBFT算法、PoW算法


参考


https://baike.baidu.com/item/拜占庭将军问题/265656 拜占庭问题


https://baike.baidu.com/item/信息论/302185 信息论


https://zhuanlan.zhihu.com/p/44024734


https://www.cnblogs.com/aspirant/p/13321203.html


https://www.cnblogs.com/aspirant/p/13321816.html


https://www.8btc.com/article/70370


https://www.jianshu.com/p/81aadcea109b

相关文章
|
算法 区块链
理解分布式一致性:拜占庭容错与PBFT
理解分布式一致性:拜占庭容错与PBFT
理解分布式一致性:拜占庭容错与PBFT
|
28天前
|
存储 负载均衡 NoSQL
【赵渝强老师】Redis Cluster分布式集群
Redis Cluster是Redis的分布式存储解决方案,通过哈希槽(slot)实现数据分片,支持水平扩展,具备高可用性和负载均衡能力,适用于大规模数据场景。
147 2
|
2月前
|
存储 缓存 NoSQL
Redis核心数据结构与分布式锁实现详解
Redis 是高性能键值数据库,支持多种数据结构,如字符串、列表、集合、哈希、有序集合等,广泛用于缓存、消息队列和实时数据处理。本文详解其核心数据结构及分布式锁实现,帮助开发者提升系统性能与并发控制能力。
|
6月前
|
数据采集 存储 数据可视化
分布式爬虫框架Scrapy-Redis实战指南
本文介绍如何使用Scrapy-Redis构建分布式爬虫系统,采集携程平台上热门城市的酒店价格与评价信息。通过代理IP、Cookie和User-Agent设置规避反爬策略,实现高效数据抓取。结合价格动态趋势分析,助力酒店业优化市场策略、提升服务质量。技术架构涵盖Scrapy-Redis核心调度、代理中间件及数据解析存储,提供完整的技术路线图与代码示例。
577 0
分布式爬虫框架Scrapy-Redis实战指南
|
2月前
|
NoSQL Redis
Lua脚本协助Redis分布式锁实现命令的原子性
利用Lua脚本确保Redis操作的原子性是分布式锁安全性的关键所在,可以大幅减少由于网络分区、客户端故障等导致的锁无法正确释放的情况,从而在分布式系统中保证数据操作的安全性和一致性。在将这些概念应用于生产环境前,建议深入理解Redis事务与Lua脚本的工作原理以及分布式锁的可能问题和解决方案。
117 8
|
4月前
|
数据采集 存储 NoSQL
基于Scrapy-Redis的分布式景点数据爬取与热力图生成
基于Scrapy-Redis的分布式景点数据爬取与热力图生成
292 67
|
7月前
|
NoSQL Java 中间件
【📕分布式锁通关指南 02】基于Redis实现的分布式锁
本文介绍了从单机锁到分布式锁的演变,重点探讨了使用Redis实现分布式锁的方法。分布式锁用于控制分布式系统中多个实例对共享资源的同步访问,需满足互斥性、可重入性、锁超时防死锁和锁释放正确防误删等特性。文章通过具体示例展示了如何利用Redis的`setnx`命令实现加锁,并分析了简化版分布式锁存在的问题,如锁超时和误删。为了解决这些问题,文中提出了设置锁过期时间和在解锁前验证持有锁的线程身份的优化方案。最后指出,尽管当前设计已解决部分问题,但仍存在进一步优化的空间,将在后续章节继续探讨。
1013 131
【📕分布式锁通关指南 02】基于Redis实现的分布式锁
|
3月前
|
缓存 NoSQL 算法
高并发秒杀系统实战(Redis+Lua分布式锁防超卖与库存扣减优化)
秒杀系统面临瞬时高并发、资源竞争和数据一致性挑战。传统方案如数据库锁或应用层锁存在性能瓶颈或分布式问题,而基于Redis的分布式锁与Lua脚本原子操作成为高效解决方案。通过Redis的`SETNX`实现分布式锁,结合Lua脚本完成库存扣减,确保操作原子性并大幅提升性能(QPS从120提升至8,200)。此外,分段库存策略、多级限流及服务降级机制进一步优化系统稳定性。最佳实践包括分层防控、黄金扣减法则与容灾设计,强调根据业务特性灵活组合技术手段以应对高并发场景。
936 7

热门文章

最新文章