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

拜占庭将军问题

背景:以战国时期为背景

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

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

问题:二忠一叛的难题

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

正常的情况:

例如:

  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.mzph.cn/news/22593.shtml

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

相关文章

JVM面试突击1

JVM面试突击 JDK,JRE以及JVM的关系 我们的编译器到底干了什么事? 仅仅是将我们的 .java 文件转换成了 .class 文件,实际上就是文件格式的转换,对等信息转换。 类加载机制是什么? 所谓类加载机制就是 虚拟机把Class文…

C语言阶段性测试题

大家好,我是深鱼~ 【前言】:本部分是C语言初阶学完阶段性测试题,最后一道编程题有一定的难度,需要多去揣摩,代码敲多了,自然就感觉不难了,加油,铁汁们!!&…

附件展示 点击下载

效果图 实现代码 <el-table-column prop"attachment" label"合同附件" width"250" show-overflow-tooltip><template slot-scope"scope"><div v-if"scope.row.cceedcAppendixInfoList &&scope.row.ccee…

路由的hash和history模式的区别

目录 ✅ 路由模式概述 一. 路由的hash和history模式的区别 1. hash模式 2. history模式 3. 两种模式对比 二. 如何获取页面的hash变化 ✅ 路由模式概述 单页应用是在移动互联时代诞生的&#xff0c;它的目标是不刷新整体页面&#xff0c;通过地址栏中的变化来决定内容区…

SQL 表别名 和 列别名

列表名 列表名之后 order by 可以用别名 也可以用原名&#xff0c; where 中不能用别名的 SQL语句执行顺序&#xff1a; from–>where–>group by -->having — >select --> order 第一步&#xff1a;from语句&#xff0c;选择要操作的表。 第二步&#xff1…

react学习笔记——1. hello react

包含的包一共有4个&#xff0c;分别的作用如下&#xff1a; babel.min.js&#xff1a;可以进行ES6到ES5的语法转换&#xff1b;可以用于import&#xff1b;可以用于将jsx转换为js。注意&#xff0c;在开发的时候&#xff0c;这个转换&#xff08;jsx转换js&#xff09;不在线上…

Tcp的粘包和半包问题及解决方案

目录 粘包&#xff1a; 半包&#xff1a; 应用进程如何解读字节流&#xff1f;如何解决粘包和半包问题&#xff1f; ①&#xff1a;固定长度 ②&#xff1a;分隔符 ③&#xff1a;固定长度字段存储内容的长度信息 粘包&#xff1a; 一次接收到多个消息&#xff0c;粘包 应…

【CI/CD】图解六种分支管理模型

图解六种分支管理模型 任何一家公司乃至于一个小组织&#xff0c;只要有写代码的地方&#xff0c;就有代码版本管理的主场&#xff0c;初入职场&#xff0c;总会遇到第一个拦路虎 git 管理流程&#xff0c;但是每一个企业似乎都有自己的 git 管理流程&#xff0c;倘若我们能掌握…

如何在不使用脚本和插件的情况下手动删除 3Ds Max 中的病毒?

如何加快3D项目的渲染速度&#xff1f; 3D项目渲染慢、渲染卡顿、渲染崩溃&#xff0c;本地硬件配置不够&#xff0c;想要加速渲染&#xff0c;在不增加额外的硬件成本投入的情况下&#xff0c;最好的解决方式是使用渲云云渲染&#xff0c;在云端批量渲染&#xff0c;批量出结…

ABAP 自定义搜索功能 demo1

ABAP 自定义搜索功能 demo1 效果&#xff1a; 双击选中行则为选中对应发票 实现 1定义 定义屏幕筛选参数 SELECTION-SCREEN BEGIN OF SCREEN 9020. SELECT-OPTIONS:s1_belnr FOR rbkp-belnr, s1_gjahr FOR rbkp-gjahr, s1_lifnr FOR rbkp-lifnr, s1_erfna FOR rbkp-erfnam, …

线程概念linux

何为线程&#xff1a; 线程是程序中负责执行的单位&#xff0c;它可以被看作是进程的一部分&#xff0c;是进程的子任务。线程与进程的区别在于&#xff0c;进程是一个资源单位&#xff0c;而线程是进程的一部分&#xff0c;它只有栈这个独立的资源&#xff0c;其他资源如代码…

Java SpringBoot集成Activiti7工作流

Activiti7 Java SpringBoot集成Activiti7工作流介绍项目集成引入依赖YML配置文件配置类 启动项目生成表结构Activiti的数据库支持 Activiti数据表介绍项目Demo地址&#xff1a; Java SpringBoot集成Activiti7工作流 本文项目Demo地址附在文章后方 官网主页&#xff1a;http://a…

组件化、跨平台…未来前端框架将如何演进?

前端框架在过去几年间取得了显著的进步和演进。前端框架也将继续不断地演化&#xff0c;以满足日益复杂的业务需求和用户体验要求。从全球web发展角度看&#xff0c;框架竞争已经从第一阶段的前端框架之争&#xff08;比如Vue、React、Angular等&#xff09;&#xff0c;过渡到…

powerdesigner各种字体设置;preview字体设置;sql字体设置

1.设置左侧菜单&#xff1a; 步骤如下&#xff1a; tools —> general options —> fonts —> defalut UI font ,选择字体样式及大小即可&#xff0c;同下图。 2.设置preview字体大小&#xff08;sql预览&#xff09; 步骤如下&#xff1a; tools —> general o…

【音频分离】demucs V3的环境搭建及训练(window)

文章目录 一、环境搭建&#xff08;1&#xff09;新建虚拟环境&#xff0c;并进入&#xff08;2&#xff09;安装pyTorch&#xff08;3&#xff09;进入代码文件夹&#xff0c;批量安装包&#xff08;4&#xff09;安装其他需要的包 二、数据集准备&#xff08;1&#xff09;下…

数据采集的方法有哪些?

近年来&#xff0c;国家和各大企业都在部署大数据战略。“大数据”这个词也越来越频繁地出现在我们的生活中。当我们在进行网上冲浪时&#xff0c;页面总会跳出我们想要搜索的相关产品或关联事物。大数据&#xff0c;似乎总是能够“算”出我们“心中所想”。那么&#xff0c;大…

SpringBoot第23讲:SpringBoot集成MySQL - 基于JPA的封装

SpringBoot第23讲&#xff1a;SpringBoot集成MySQL - 基于JPA的封装 在实际开发中&#xff0c;最为常见的是基于数据库的CRUD封装等&#xff0c;比如SpringBoot集成MySQL数据库&#xff0c;常用的方式有JPA和MyBatis&#xff1b; 本文是SpringBoot第23讲&#xff0c;主要介绍基…

JVM基础篇-直接内存

JVM基础篇-直接内存 什么是直接内存? 直接内存( 堆外内存 ) 指的是 Java 应用程序通过直接方式从操作系统中申请的内存,这块内存不属于jvm 传统方式读取文件 首先会从用户态切换到内核态&#xff0c;调用操作系统函数从磁盘读取文件&#xff0c;读取一部分到操作系统缓冲区…

openGauss学习笔记-29 openGauss 高级数据管理-UNION子句

文章目录 openGauss学习笔记-29 openGauss 高级数据管理-UNION子句29.1 语法格式29.2 示例29.2.1 UNION29.2.2 UNION ALL openGauss学习笔记-29 openGauss 高级数据管理-UNION子句 UNION计算多个SELECT语句返回行集合的并集。UNION内部的SELECT语句必须拥有相同数量的列&#…

新一代开源流数据湖平台Apache Paimon入门实操-上

文章目录 概述定义核心功能适用场景架构原理总体架构统一存储基本概念文件布局 部署环境准备环境部署 实战Catalog文件系统Hive Catalog 创建表创建Catalog管理表查询创建表&#xff08;CTAS&#xff09;创建外部表创建临时表 修改表修改表修改列修改水印 概述 定义 Apache Pa…