分布式与一致性协议之PBFT算法(二)

PBFT算法

如何替换作恶的主节点

虽然PBFT算法可以防止备份节点作恶,因为这个算法是由主节点和备份节点组成的,但是,如果主节点作恶(比如主机点接收到了客户端的请求,但就是默不作声,不执行三阶段协议),那么无论正常节点数有多少,备份节点肯定无法达成共识,整个集群也将无法正常运行。针对这个问题,我们该如何解决呢?
答案是视图变更,也就是通过领导者选举楚新的主节点,并替换掉作恶的主节点。(其中的"视图"可以理解为领导者任期内不同的视图值对应不同的主节点,比如,视图值为1时,主节点为A;视图值为2时,主节点为B)
需要注意的是,对于领导者模型算法而言,不管是非拜占庭容错算法(比如Raft算法)还是拜占庭容错算法(比如PBFT算法),领导者选举都是它们实现容错能力非常重要的一环。比如,对Raft算法而言,领导者选举实现了领导者节点的容错能力,避免了因领导者节点故障而导致的整个集群不可用的问题。而对PBFT算法而言,视图变更,除了能解决主节点故障导致的集群不可用的问题之外,还能解决主节点是恶意节点的问题。
既然领导者选举这么重要,那么PBFT算法到底是如何实现视图变更的呢?

主节点作恶会出现什么问题

在PBFT算法中,主节点作恶有如下几种情况:

  • 1.主节点接收到客户端请求后不做任何处理,也就是默不作声
  • 2.主节点接收到客户端请求后给不同的预准备请求分配不同的序号
  • 3.主节点只给部分系欸但发送预准备消息
    需要注意的是,不管出现哪种情况,共识都是无法达成的,也就是说,如果恶意节点当选了主节点,此时无论忠诚节点数有多少,忠诚节点们都将无法达成共识。而这种情况肯定是无法接受的,这需要我们设计一个机制,在发现主节点可能作恶时,将作恶的主节点替换掉,并保证最终只有忠诚的节点担任主节点。这样,PBFT算法才能保证当节点数为3f+1(其中f为恶意节点数)时,忠诚的节点们能就客户端提议的指令达成共识,并执行一致的指令。
    那么,在PBFT算法中,视图变更是如何选举出新的主节点并替换掉作恶的主节点呢?

如何替换作恶的主节点

在我看来,视图变更是保证PBFT算法稳定运行的关键。当系统运行异常时,客户端或备份节点出发系统的视图变更,通过"轮流上岗"的方式(公式是(V+1) mod |R|, 其中v为当前视图的值,|R|为节点数)选出下一个视图的主节点,最终选出一个忠诚、稳定运行的新主节点,并保证了共识的达成。为了更好地理解视图变更的原理,继续以苏秦为例展开分析,这次,咱们把叛徒楚当作"大元帅",让它扮演主节点的角色,如图所示。在这里插入图片描述

首先,苏秦联系楚,向楚发送包含作战指令"进攻"的请求,如图所示。在这里插入图片描述

当楚接收到苏秦的请求之后,为了达到破坏作战计划的目的,它选择默不作声,心想:我就是不执行三阶段协议,不执行你的指令,也不通知其他将军执行你的指令,你能把我怎么办?
结果,苏秦始终没有接收到两个相同的响应消息。待过了约定的事件后,苏秦会认为也许各位将军们出了什么问题。这时苏秦会直接给各位将军发送作战指令,如图所示。在这里插入图片描述

当赵、魏、韩接收到来自苏秦的作战指令时,它们会将作战指令分别发送给楚,并等待一段时间,如果在这段事件内它们仍未接收到来自楚地预准备消息,那么它们就认为楚可能已经叛变了,并发起视图变更(采用"轮流上岗"的方式选出新的大元帅,比如赵),向集群所有节点发送视图变更消息,如图所示。在这里插入图片描述

当赵接收到两个视图变更消息后,它就会发送新视图消息给其他将军,告诉大家,我是大元帅了,如图所示。在这里插入图片描述

其他将军在接收到新视图消息后,就认为选出了新的大元帅。然后,忠诚的将军们就可以一致地执行来自苏秦的作战指令了。
你看,叛变的大元帅就这样被发现和替换掉了,而最终大元帅一定是忠诚的。
回到计算机的世界中,我们应该如何理解呢?其实现原理与签名一样,这里不再赘述。不过为了更全面地理解视图变更,补充几点。
首先,当一个备份节点在定时器超时出发了视图变更后,它将暂时停止接收和处理除了检查点(CHECKPOINT)、视图变更、新视图之外的消息。你可以这样理解,这个节点认为现在集群处于异常状态,所以不能再处理客户端请求相关的消息。
其次,除了演示中触发备份节点进行视图变更的情况,下面几种情况也会触发视图变更,列举如下:

  • 1.备份节点发送了准备消息后,在约定的时间内未接收到来自其他节点的2f个相同的准备消息
  • 2.备份节点发送了提交消息后,在约定的时间内危机收到来自其他节点的2f个相同的提交消息
  • 3.备份节点接收到异常消息,比如视图值、序号和已接收的消息相同,但内容摘要不同。
    也就是说,视图变更除了能解决主节点故障和作恶的问题,还能避免备份节点长时间阻塞等待客户端请求被执行的情况。
    最后需要大家注意的是,Raft算法的而领导者选举和日志提交都是由集群的节点来完成的。但在PBFT算法中,客户端参与了拜占庭容错的实现,比如,客户端实现定时器,等待接收来自备份节点的响应,如果等待超时,则发送请求给所有节点

注意

相比Raft算法完全不适应有人作恶的场景,PBFT算法能容忍(n-1)/3个恶意节点(也可以是故障节点)。另外,相比Pow算法,PBFT算法的有点是不消耗算力,所以在日常实践中,PBFT算法比较适用于相对"可信"的场景,比如联盟链

PBFT算法的局限、解决办法和应用

如同一枚硬币具有正反两面,任何一个算法也会有优缺点,PBFT算法也不例外。接下来,将介绍PBFT算法的局限、解决办法,以及实际应用情况。
首先,在一般情况下,每个节点都需要持久化保存状态数据(比如准备消息),以便后续使用,但随着系统运行,数据会越来越多,最终肯定会出现存储空间不足的情况,那么,怎么解决这个问题?
答案是检查点机制,PBFT算法实现了检查点机制,来定时清理节点缓存在本地但已经不再需要的历史数据(比如预准备消息、准备消息和提交消息),节省了本地的存储空间,且不会影响系统的运行。
其次,我们都知道基于数字签名的加解密非常消耗性能,这也是为什么在一些对加解密要求高的场景中,大家常直接在硬件中实现加解密,比如IPSEC VPN。如果在PBFT算法中,所有消息都是签名消息,那么肯定非常消耗性能,且会极大地制约PBFT算法的落地场景,那么有什么办法优化这个问题吗?
答案是将数字签名和消息验证码(MAC)混合使用。具体来说,在PBFT算法中,只有视图变更消息和新视图消息采用签名消息,其他消息则采用消息验证码,这样一来,就可以节省大量加解密的性能开销。
最后,PBFT算法是一个能在实际场景中落地的拜占庭容错算法,它和区块链也结合紧密,具体有以下几个应用:

  • 1.相对可信、有许可限制的联盟链,比如Hyperledger Sawtooth
  • 2.与其他拜占庭容错算法结合来落地公有链,比如Zilliqa,将Pow算法和PBFT算法结合起来,实现公有链的共识协商。具体来说,PoW算法用于认证,证明节点不是"坏人",PBFT算法用于实现共识。针对PBFT算法消息数过多、不适应大型分布式系统的痛点,Zilliqa实现了分片(Sharding)技术。
    另外,也有团队因为PBFT算法消息数过多、不适应大型分布式系统的痛点,放弃使用PBFT算法,而是通过法律来约束"节点作恶"的行为,比如IBM的Hyperledger Fabric。技术是发展的,适合的才是最好的。在实际工作中,建议根据场景的可信度来决定是否采用PBFT算法,是否改进和优化PBFT算法。

重点总结

  • 1.PBFT算法是通过签名(或消息认证码MAC)来约束恶意节点的行为,同时采用三阶段协议,基于大多数原则达成共识的。另外,与口信消息型拜占庭问题之解(以及签名消息型拜占庭问题之解)不同的是,PBFT算法实现的是一系列值得共识,而不是单值的共识。
  • 2.客户端通过等待f+1个相同响应消息超时来发现主节点可能在作恶,此时客户端会发送客户端请求给所有集群节点,从而触发可能的视图变更。与Raft算法在领导者期间服务不可用类似,在视图变更时,PBFT集群也是无法提供服务的。

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

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

相关文章

Line Buffer概述

buffer在芯片物理上一般指的是SRAM,也可以指寄存器组。buffer的作用是用来在逻辑芯片上暂时存储数据,但不会是大量的数据。如果是大量数据一般会使用DRAM(典型的指DDR)作为存储芯片,用来存储大密度数据。line buffer可…

优化资源利用,用C++内存池点亮编程之路

内存池介绍(Memory Pool): 它是一种内存分配方式,通过预先分配和复用内存块。 在真正使用内存之前,先申请一大块内存备用。当有新的内存需求时,就从内存池中分出一部分内存块, 若内存块不够再继续申请新的内存。如果我们不需要…

环形链表(判断链表中是否有环)的讲解

一:题目 二:思路讲解 1:采用快慢指针的方法,一个fast指针一次移动两个节点,一个slow指针一次移动一个节点。 2:两个指针从头指针开始往后遍历,如果fast指针或者fast->next 有一个为空&…

5款可用于LLMs的爬虫工具/方案

5款可用于LLMs的爬虫工具/方案 Crawl4AI 功能: 提取语义标记的数据块为JSON格式,提供干净的HTML和Markdown文件。 用途: 适用于RAG(检索增强生成)、微调以及AI聊天机器人的开发。 特点: 高效数据提取,支持LLM格式,多U…

c++ 入门2

目录 五. 函数重载 1、参数类型不同 2、参数个数不同 3、参数类型顺序不同 C支持函数重载的原理--名字修饰(name Mangling) 为什么C支持函数重载,而C语言不支持函数重载呢? 六. 引用 6.1 概念 6.2 引用特性 6.3 常引用 6.4 使用场景 …

美国政府发布新的国际网络空间和数字政策战略(下)

文章目录 前言五、当前时期的特征六、战略的畅想前言 该战略提出,2020年代是决定性的十年,当前采取的行动将塑造未来网络空间、数字技术和数字经济的“轮廓”;在实施该战略时,美国务院将与国会和机构间合作伙伴合作,评估当前的网络授权,并根据需要修改或创建授权,以便跟…

数据结构之排序(上)

片头 嗨,小伙伴们,大家好!我们今天来学习数据结构之排序(上),今天我们先讲一讲3个排序,分别是直接插入排序、冒泡排序以及希尔排序。 1. 排序的概念及其应用 1.1 排序的概念 排序&#xff1a…

图书馆APP开发解决方案

uni-app框架:使用Vue.js开发跨平台应用的前端框架,编写一套代码,可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言:pythonjavanode.jsphp均支持 运行软件…

docker 部署并运行一个微服务

要将微服务部署并运行在Docker容器中,你需要按照以下步骤操作: 编写Dockerfile:在项目根目录下创建一个名为Dockerfile的文件,并添加以下内容: # 使用一个基础的Docker镜像 FROM docker-image# 将项目文件复制到容器…

C++中合成的默认构造函数的访问权限

问题 我们知道,在C中,如果没有为一个类显式定义构造函数,那么编译器会为我们隐式地定义一个默认构造函数。那么,你有没有想过,这个隐式定义地默认构造函数(合成的默认构造函数)的访问权限是什么…

蓝桥杯备战10.分巧克力

P8647 [蓝桥杯 2017 省 AB] 分巧克力 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 暴力枚举 过70%样例 #include<bits/stdc.h> #define endl \n #define int long long using namespace std; const int N 2e710,M 1e310; int n,k; int h[N],w[N]; bool check(int …

js的传参方法

在JavaScript中&#xff0c;有几种不同的方式可以向函数传递参数&#xff08;传参&#xff09;。以下是一些主要的方法&#xff1a; 位置参数&#xff08;Positional Parameters&#xff09; 这是最常见的传参方式。在定义函数时&#xff0c;你指定参数的名称&#xff0c;然后…

百度云防护如何开启CC攻击防护

百度云防护的最重要的功能是可以CC攻击防护&#xff0c;针对CC攻击&#xff0c;百度云防护有被动的CC攻击拦截规则&#xff0c;也有主动自定义访问策略拦截。 今天百度云来教大家如何开启百度云防护的CC攻击防御功能。 1.进入防护模板功能-创建模板 2.开启CC攻击防御功能&…

李飞飞首次创业!

B站&#xff1a;啥都会一点的研究生公众号&#xff1a;啥都会一点的研究生 最近AI又有啥进展&#xff1f;一起看看吧~ 中国独角兽企业已达369家&#xff0c;六成以上与AI、芯片等硬科技赛道有关 2024中关村论坛“全球独角兽企业大会”上发布全新《中国独角兽企业发展报告&am…

探索互联网医院系统源码:开发在线药房小程序实战教学

今天&#xff0c;笔者将与大家一同深入探讨互联网医院系统的源码结构&#xff0c;并通过开发在线药房小程序的实战教学&#xff0c;为读者提供一种学习和理解这一领域的途径。 一、互联网医院系统源码解析 1.技术选型 互联网医院系统的开发离不开合适的技术选型&#xff0c;…

JavaScript(进阶)

作用域 了解作用域对程序执行的影响及作用域链的查找机制&#xff0c;使用闭包函数创建隔离作用域避免全局变量污染。 作用域&#xff08;scope&#xff09;规定了变量能够被访问的“范围”&#xff0c;离开了这个“范围”变量便不能被访问&#xff0c;作用域分为全局作用域和局…

类和对象-Python-第二部分

师从黑马程序员 多态 抽象类&#xff08;接口&#xff09; #演示抽象类 class AC:def cool_wind(self):"""制冷"""passdef hot_wind(self):"""制热"""def swing_l_r(self):"""左右摆风""…

Cloudflare国内IP地址使用教程

Cloudflare国内IP地址使用教程 加速网站&#xff1a; 首先我们添加一个 A 记录解析&#xff0c;解析 IP 就是我们服务器真实 IP&#xff1a; 然后侧边栏 SSL/TLS - 自定义主机名&#xff1a; 回退源这里填写你刚刚解析的域名&#xff0c;保存后回退源状态为有效再来接下的操作…

第十二篇:数据库系统导论 - 探索数据管理的基石

数据库系统导论 - 探索数据管理的基石 1 引言 数据的力量&#xff1a;揭秘数据库系统的核心 在信息时代&#xff0c;数据无处不在&#xff0c;它们成为了企业和社会运作的基础。我们如何储存、检索、更新和维护这些数据&#xff0c;决定了我们能否从这些数据中获得力量。数据…

JAVA基础-----泛型

三、泛型接口 1、基本语法&#xff1a; public interface 接口名<类型参数> {... }2、泛型接口中的类型参数&#xff0c;在该接口被继承或者被实现时确定。解释如下&#xff1a; &#xff08;1&#xff09;在泛型接口中&#xff0c;静态成员也不能使用泛型接口定义的类…