分布式协议与算法——拜占庭将军问题

news2024/11/22 16:34:44

拜占庭将军问题

背景:以战国时期为背景

战国时期,齐、楚、燕、韩、赵、魏、秦七雄并立,后来秦国的势力不断强大起来,成了东方六国的共同威胁。于是,这六个国家决定联合,全力抗秦,免得被秦国各个击破。一天,苏秦作为合纵长,挂六国相印,带着六国的军队叩关函谷,驻军在了秦国边境,为围攻秦国作准备。但是,因为各国军队分别驻扎在秦国边境的不同地方,所以军队之间只能通过信使互相联系,这时,苏秦面临了一个很严峻的问题:如何统一大家的作战计划?

万一一些诸侯国在暗通秦国,发送误导性的作战信息,怎么办?如果信使被敌人截杀,甚至被敌人间谍替换,又该怎么办?这些都会导致自己的作战计划被扰乱,然后出现有的诸侯国在进攻,有的诸侯国在撤退的情况,而这时,秦国一定会趁机出兵,把他们逐一击破的。

问题:二忠一叛的难题

现有三个国家攻打秦国,分别叫齐、楚、燕。同时,又因为秦国很强大,所以只有半数以上的将军参与进攻,才能击败敌人。此时,将军们需要通过信使传递消息,然后协商一致之后,才能在同一时间发动进攻。

正常的情况:

例如:

  1. 齐根据侦查情况决定撤退。
  2. 楚和燕根据侦查信息,决定进攻。

这样最终进攻和撤退的二者的占比为2:1,因此最终会执行进攻的命令。

不正常的情况,存在叛军(恶意节点):

假设齐和燕为忠诚将军,楚为叛将。现在齐决定撤退、燕决定进攻。而由于楚已经叛变,他向齐传达“撤退”的命令,向燕传达“进攻”的命令。因此齐看到的结果为:进攻:撤退 = 1:2;燕看到的结果为:进攻:撤退 = 2:1。最终就燕自己去进攻秦军了,被灭了。

解决方法一:口信消息型拜占庭问题之解

三位将军分拨一部分军队,由苏秦带领。这样3位将军的作战讨论,变成了4位将军的作战讨论,这样可以增加讨论中忠诚将军的数量。

然后,四位将军约定了,如果没有收到命令,就执行预设的默认命令,例如撤退。需要进行多轮作战信息协商(协商的轮次与叛将的数量有关):

第一轮:

  • 先发送作战信息的将军作为指挥官,其他的将军作为副官;
  • 指挥官将他的作战信息发送给每位副官;
  • 每位副官,将从指挥官处收到的作战信息,作为他的作战指令;如果没有收到作战信息,将把默认的“撤退”作为作战指令。

第二轮:

  • 除了第一轮的指挥官外,剩余的 3 位将军将分别作为指挥官,向另外 2 位将军发送作战信息;
  • 然后,这 3 位将军按照“少数服从多数”,执行收到的作战指令。

如果这里需要协商多轮,那么除了前面几轮的指挥官外,剩余的将军作为指挥官将作战信息发送每位副官。

具体协商过程:

分别以忠诚将军和叛将先发送作战信息为例:

1、忠诚将军先发送作战信息:

假设忠将苏秦先发送作战信息,作战指令是“进攻”。那么在第一轮作战协商中,苏秦向齐、楚、燕发送作战指令“进攻”,意味着齐、楚、燕分别收到了“进攻”的信息,并作为自己的作战指令

第二轮作战信息协商中,齐、楚、燕分别作为指挥官,分别向另外两位(第一轮指挥官苏秦除外)发送作战信息“进攻”。由于楚已经叛变,他为了干扰作战计划,向另外两位将军发送了“撤退”作战命令。

最终,齐和燕收到的作战信息都是“进攻、进攻、撤退”。按照少数服从多数的原则,执行“进攻”指令,实现了作战计划的一致性。

2、叛将先发送作战信息:

当叛将先发送作战消息,干扰作战计划时。在第一轮协商中,楚向苏秦发送“进攻作战指令”,向齐、燕发送“撤退”作战指令。苏秦、齐、燕收到后并将其作为自己的作战指令

在第二轮作战信息协商中,苏秦、齐、燕分别作为指挥官,向另外两位发送作战信息。

最终苏秦、齐、燕收到的信息都是“撤退、撤退、进攻”,按照少数服从多数的原则,执行“撤退”指令,实现了作战计划的一致性。

这个算法的前提:

  1. 如果叛将人数为m,将军人数不能少于3m+1(也就是:n位将军,最多能容忍(n-1)/3 位叛将)。
  2. 叛将数m决定递归循环的次数(进行多少轮作战信息协商),即m+1轮。

二忠一叛问题中,在存在1位叛将的情况下,必须增加1位将军。那么有没有办法在不增加将军人数的时候,直接解决二忠一叛的难题?可以通过签名消息型拜占庭问题之解进行解决。

解决办法二:签名消息型拜占庭问题之解

还可以通过签名的方式,在不增加将军人数的情况下,解决二忠一叛的难题。签名具有如下的特性:

  • 忠诚将军的签名无法伪造,而且对他签名消息的内容进行任何更改都会被发现;
  • 任何人都能验证将军签名的真伪。

与口信消息型拜占庭问题之解类似,签名消息型拜占庭问题之解同样需要多轮协商。协商的过程也与口信消息型拜占庭问题之解类似,但最终执行作战计划时并不是使用少数服从多数的原则。下面同样以忠诚将军和叛将分别先发送消息为例。

忠诚将军先发送消息

第一轮协商中,忠诚将军齐分别向楚和燕发送“进攻”的作战信息,燕和楚收到进攻的作战信息后将其作为自己的作战消息。

第二轮协商中,楚和燕分别作为指挥官分别向另一位将军(第一轮将军除外)发送作战信息。叛将楚修改或伪造作战信息,将“撤退”信息发送给了燕。那么燕在收到楚的作战信息的时候,会发现齐的作战信息被修改,楚已经叛变,这是燕会忽视来自楚的作战信息,最终执行齐发送的作战信息。

叛将先发送消息

第一轮协商中,叛将楚向齐发送“撤退”的作战消息,向燕发送“进攻”的作战消息。

第二轮协商中,燕和齐分别作为指挥官分别向另一位将军(第一轮将军除外)发送作战信息。此时齐收到了[撤退、进攻]两个作战消息,燕收到了[进攻、撤退]两个作战消息。但是齐和燕会按照一定的规则在排序后的所有已接受的指令中选取一个(例如按照排序规则后的作战顺序为[进攻,撤退],都选择第一个作战计划)作战计划进行执行。最终执行一致的作战计划。

齐、燕收到的信息列表是内容是一样的,只是顺序不一样,使用相同的排序算法,选取策略,可以保证选取的指令时一样的

这个算法的前提是:

1、n位将军,最多允许 (n-2)位叛将。

2、同样需要多轮协商,如果叛将数位m,那么需要m + 1轮协商。

那如何实现签名消息呢?

可以使用非对称加密算法(如RSA),发送方使用哈希算法(如MD5)进行摘要,然后使用私钥对摘要进行加密,生成数字签名。然后将加密摘要和消息一起发送给接受方。接受方收到消息和加密摘要后,会用公钥对加密摘要进行解密,并对消息内容进行摘要,将两个摘要进行对比,以判断消息是否被篡改。

私钥加密,公钥解密。可以保证消息不会被冒充,因为私钥是不可泄漏的。如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的。

感觉使用签名消息型拜占庭问题之解会更消耗算力一点。

小结

将将军作战中的场景与计算机世界的分布式场景进行对应:

  • 故事里的将军,可以理解为计算机节点。
  • 忠诚将军,可以理解为正常运行的计算机节点。
  • 叛变将军,可以理解为出现故障并会发送误导信息的计算机节点。
  • 信使被杀,可以理解为通讯故障、信息丢失。
  • 信使被间谍替换,可以理解为通讯被中间人攻击,攻击者在恶意伪造信息和劫持通讯。

拜占庭将军问描述的是最困难的,也是最复杂的一种分布式故障场景,除了存在故障行为,还存在恶意行为的场景。因此在存在恶意行为的场景中(如数字货币的区块链技术中),必须使用拜占庭容错算法(Byzantine Fault Tolerance,BFT)。除了上面提到的两种算法(口信消息型拜占庭问题之解、签名消息型拜占庭问题之解),常用的拜占庭容错算法还有:PBFT算法,PoW算法。

在计算机分布式系统中,最常用的是非拜占庭容错算法,即故障容错算法(Crash Fault Tolerance,CFT)CFT 解决的是分布式的系统中存在故障,但不存在恶意节点的场景下的共识问题。 也就是说,这个场景可能会丢失消息,或者有消息重复,但不存在错误消息,或者伪造消息的情况。常见的算法有 Paxos 算法、Raft 算法、ZAB 协议。

参考

  • 分布式协议与算法实战 学习笔记

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/850954.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

go错误集(持续更新)

1.提示以下报错 Build Error: go build -o c:\Users\Administrator\Desktop__debug_bin2343731882.exe -gcflags all-N -l . go: go.mod file not found in current directory or any parent directory; see ‘go help modules’ (exit status 1) 解决办法: go …

mysql进阶篇(二)

前言 「作者主页」:雪碧有白泡泡 「个人网站」:雪碧的个人网站 「推荐专栏」: ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄,vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

知识贴:如何使用校对软件改善新闻稿件的质量

使用校对软件改善新闻稿件的质量可以按照以下步骤进行: 1.选择适合的校对软件:市场上有许多校对软件可供选择,例如语法和拼写检查工具,自动校对工具以及专门为新闻写作而设计的工具。根据自己的需求和预算,选择最适合的…

山西电力市场日前价格预测【2023-08-09】

日前价格预测 预测明日(2023-08-09)山西电力市场全天平均日前电价为335.82元/MWh。其中,最高日前电价为364.48元/MWh,预计出现在19: 45。最低日前电价为306.83元/MWh,预计出现在13: 30。 价差方向预测 1: 实…

C语言__LINE__和#line学习

这是ANSI C 预定义的, __LINE__ ,包含当前行号,一个十进制常量; #line指令用于改变 __LINE__的内容; 先看一下VC6控制台程序, printf这行是第五行,输出了 5 ; 使用#line重新定义了…

Java源码解析-重点集合框架篇

Java 源码解析,集合篇 一:故事背景二:数据结构2.1 线性结构2.2 非线性结构 三:集合分类3.1 结构图 四:详细分析4.1 List4.1.1 ArrayList4.1.1.1 底层结构4.1.1.2 主要特点 4.1.2 LinkedList4.1.2.1 底层结构4.1.2.2 主…

SAM 大模型Colab快速上手【Segment Anything Model】

Google Colab 是一个基于云的 Jupyter 笔记本环境,允许您通过浏览器编写、运行和共享 Python 代码。 它就像 Google 文档,但用于代码。 通过免费版本的 Google Colab,你可以获得带有约 16GPU VRAM 的 Nvidia Tesla T4 GPU,这对于…

2023牛客暑期多校训练营6

参考2023牛客暑期多校训练营6(G、E、C、B、A) - 知乎 (zhihu.com) 纯数学,推式子 从贡献度的角度考虑 首先,当两个子集大小均相同时,才有可能变相同 其次是我们需要先将S和T中的数分别从小到大排个序,然后要变相同花费最小,肯定是对齐的数之间变换,可…

【力扣每日一题】2023.8.8 任意子数组和的绝对值的最大值

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一个数组,让我们找出它的绝对值最大的子数组的和。 这边的子数组是要求连续的,让我们找出一个元素之和…

Cadvisor+InfluxDB+Grafan+Prometheus(详解)

目录 一、CadvisorInfluxDBGrafan案例概述 (一)Cadvisor Cadvisor 产品特点: (二)InfluxDB InfluxDB应用场景: InfluxDB主要功能: InfluxDB主要特点: (三&#…

【mock安装时报错】

node版本需要大于16 切换>16的版本即可 建议使用 nvm进行 node版本状态管理 可参考另一篇文章 nvm多版本管理方案

2021年09月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题(共25题,每题2分,共50分) 第1题 取整除的运算符是? A:/ B:// C: D:** 正确的答案是:B://。 解析:在Python中,取整除的运算符是双斜杠(//)。它执行除法运算并返回结果的整数部分,即向下取整。相比之下,除法运算符(/)返回的是精确的浮点数结…

C语言数组第十课---------------三子棋-------数组经典练手题

作者前言 🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂 🎂 作者介绍: 🎂🎂 🎂…

从0到1搭建uniapp

一、什么是uniapp UniApp是一款基于Vue.js框架的全端开发工具,可以实现同时开发多个平台(包括H5、小程序、APP等)应用的能力。使用UniApp,开发者只需要编写一份代码就可以快速地发布到多个平台,极大地提高了开发效率和…

java实现当前系统时间格式化

import java.text.SimpleDateFormat; import java.util.Date;public class DateTest {public static void main(String[] args) {Date date new Date();System.out.println("当前系统时间:" date);SimpleDateFormat simpleDateFormat new SimpleDateFo…

MySQL 查询语句大全

目录 基础查询 直接查询 AS起别名 去重(复)查询 条件查询 算术运算符查询 逻辑运算符查询 正则表达式查询⭐ 模糊查询 范围查询 是否非空判断查询 排序查询 限制查询(分页查询) 随机查询 分组查询 HAVING 高级查询…

数据结构和算法三(排序)

列表排序 排序类型&#xff1a; 一、冒泡排序&#xff1a; 屏幕录制2023-07-25 13.05.12 def bubble_sort(li):exchangeFalseif len(li)<1:return lifor i in range(len(li)-1):for j in range(len(li)-i-1):if li[j]>li[j1]:li[j],li[j1]li[j1],li[j]print(li)exchangeT…

【数理知识】奇异值分解,从数据的线性变换角度来理解

序号内容1【数理知识】自由度 degree of freedom 及自由度的计算方法2【数理知识】刚体 rigid body 及刚体的运动3【数理知识】刚体基本运动&#xff0c;平动&#xff0c;转动4【数理知识】向量数乘&#xff0c;内积&#xff0c;外积&#xff0c;matlab代码实现5【数理知识】协…

学习电气工程的关键要点

基础知识&#xff1a;学习电路原理、电子器件、电机原理等基础知识。可以通过自学、培训或相关专业课程来学习。 编程技能&#xff1a;掌握一门编程语言&#xff0c;如C语言或MATLAB。电气工程常需要编程来设计和实现控制系统。 自动化控制理论&#xff1a;了解自动化控制系…

Python web实战之Django 的 RESTful API 设计详解

关键词: Python, Web 开发, Django, RESTful API 1 API的一些事儿 1.1 什么是API&#xff1f; API是应用程序编程接口&#xff08;Application Programming Interface&#xff09;的缩写。它是一种定义了不同软件组件之间交互方式的规范。API允许不同的应用程序之间进行通信和…