PBFT共识算法

一、拜占庭将军问题

古代,拜占庭的各地的将军去打仗,比如有10个,必须相互通信,达成共识才能一起出发,否则战役失败。

问题1、有个将军会叛变,在有将军叛变的情况下,如何达成共识。

问题2、互相通信的信道必须是安全的,在不安全的信道中通讯,达成共识很困难的。

已经证明:在背叛者为f,将军总数>3f时,可达成共识。3f+1<=n---->(n-1)/3

容错节点:应为硬件或者网络问题,节点无响应。

作恶节点:除了无响应,还可以发除错误的信息,误导其他人。

raft 可容忍的错误节点数 f = (n-1)/2

设节点总数为n,错误节点为f,根据共识定理,只有比f多1个就可以既f+1,f+f+1 = n

2f+1=n-->f = (n-1)/2 综上所述,作恶节点个数最多为(n-1)/2个,系统可达成共识。

PBFT可容忍的非正确节点的个数为f =(n-1)/3

1、情况1、假设节点总数为n,作恶节点为f,错误节点个数为f,作恶节点被发现后,会被系统剔除,那么完好节点只要比错误的节点多1个,既f+1就可以了。那么f+f+f+1 = n-->3f+1=n ----> f=(n-1)/3

2、情况2、作恶节点与错误节点个数相同,同raft。

基本流程:

1、客户端给主节点发送情况,

2、主节点将请求广播给其他节点,其他节点做三阶段处理。

3、节点处理完成后,落盘,返回给客户端。

4、客户端收到f+1个正确消息后,代表共识结束。

三阶段处理:

pre-pre、promise、commit

消息类型<v,n,d,m>

v是主节点选举的第几轮,1,2。。。等等

n是客户端发过来的请求的编号

d是消息内容的摘要

m是消息的内容

主节点收到消息会向其他节点发送pre-prepare消息。开始三阶段处理

1、非主节点收到pre-prepare消息,判断接受不接受。不接受的逻辑,与第一次收到的消息相比较,是V,n相同,但d和M不同,及不是这个消息。或者请求编号不在高低水位之间。

2、如果接受pre-prepare消息,则想其他节点广播发送promise消息,其他节点也做同样的事情,如果1个节点收到超过2f+1个promise消息,则进入commit阶段。

3、节点会将向外广播commit消息,其他节点也在做同样的操作。当收到2f+1个commit消息时,则认为大多数节点都commit了,这时候就会落盘,向客户端发送正确消息。

View change(视图改变)

更换主节点,当主节点挂了,或者其他从节点认为主节点作恶,就会触发view change。

过程分view-change,view-change-ack,new-view

当主节点挂了,从节点想其他节点发出view-change消息,其中编号最小的节点会成为主节点,当新主节点收到2f+1个节点的view-change消息,就认为大家都同一它成为新节点。那他就会发出new-view消息,接着处理上个视图没处理完的请求。

垃圾回收

checkpoint和stable checkpoint和高低水位

checkpoint当前节点处理的最新请求序号号。

stable checkpoint 大部分节点2f+1个节点已经共识完成的请求序列号。

stable checkpoint是为了减少数据的占用空间,它之前的请求都可以删除掉。每个节点不用再存所有的请求了,节省了节点的空间。

节点i会给其他节点发送<checkpoint ,n,d,i>

n是当前节点的请求序列号。

d是当前状态的一个摘要。

当收到2f+1个节点的回复时,就认识大多数人都处理到这个请求序列号了,那么就会形成stable checkpoint。

如果收到i节点消息的其他节点,没有处理到这个请求序列号,那么就不会返回消息。

高低水位

低水位为上一次的stable checkpoint,高水位为低水位+L(L为我们设定的值)。

当节点i的处理请求序列号超过高水位,就等待,不处理了,等待stable checkpoint变化后,再继续处理。

 

raft和PBFT的时间复杂度。

raft的复杂度O(n),共识分为日志记录,提交数据2部分,都是主节点给从节点发送数据,从节点之间是不需要沟通的,从节点回复接受或者不接受。

日志记录阶段,请求数n-1。提交数据阶段,请求数n-1。总的是2n-2。

PBFT的时间复杂度O(n),的pre-pepare阶段,主节点发送给所有从节点,请求数为n-1,

promise阶段,每个从节点给每个其他节点发送,请求数为n*(n-1)

commit阶段,每个从节点给每个其他节点发送,请求数也没n*(n-1)

raft不会质疑主节点,pbft会质疑主节点。

 

 

### 回答1: PBFT(Practical Byzantine Fault Tolerance)共识算法是一种分布式系统中的共识算法,它用于在存在恶意节点的情况下达成一致。在Go语言中,可以使用Go的标准库以及第三方库来实现PBFT共识算法。 具体实现步骤如下: 1. 定义网络中的节点数量以及角色(例如:主节点,从节点)。 2. 实现请求阶段,即请求节点向其他节点发送请求消息。 3. 实现预备阶段,即其他节点对请求消息进行验证,如果足够多的节点同意,则进入下一个阶段。 4. 实现提交阶段,即同意请求的节点向其他节点发送提交消息。 5. 实现确认阶段,即其他节点对提交消息进行验证,如果足够多的节点同意,则完成共识。 实现PBFT共识算法需要对分布式系统和网络通信等方面有较深的了解,如果不熟悉可以先学习相关知识。 ### 回答2: Golang语言是一种由Google开发的开源编程语言,具有高效的并发性能和简单的语法。实现PBFT共识算法使用Golang语言可以提供良好的可读性和易于维护的代码。 PBFT(Practical Byzantine Fault Tolerance)共识算法是一种经典的拜占庭容错共识算法,用于在分布式系统中达成一致的决策。它可以容忍最多 f 个节点(其中 f 是拜占庭错误数),并确保所有正确节点在有限时间内达成一致。 在使用Golang实现PBFT共识算法时,我们可以使用Golang的并发机制,如goroutine和channel,来实现节点之间的消息传递和状态同步。 首先,我们需要定义一个PBFT节点的结构体,包含节点的标识符、状态、消息队列等信息。然后,我们可以使用goroutine创建多个节点,并通过channel进行通信。 在PBFT算法中,节点需要按照一定规则进行投票,并等待足够多的节点达成一致后才能继续执行下一步操作。我们可以使用Golang的select语句和channel来实现这一过程,通过select语句监听不同的channel,根据接收到的消息进行相应的操作。 在实现PBFT算法的消息传递过程中,我们可以使用Golang的网络编程库,如net包,来模拟节点之间的网络通信。节点之间可以通过TCP或UDP协议进行消息的传递和接收。 最后,我们需要编写一些测试用例来验证PBFT共识算法的正确性和性能。使用Golang的测试框架,例如testing包,可以方便地编写单元测试和性能测试。 总之,使用Golang语言实现PBFT共识算法可以充分发挥Golang的并发性能和简洁的语法特性。通过合理地利用Golang的并发机制和网络编程库,我们可以实现一个高效可靠的PBFT共识算法,并进行相关的测试和验证。 ### 回答3: Golang语言可以用于实现PBFT(Practical Byzantine Fault Tolerance)共识算法PBFT是一种拜占庭容错的共识算法,适用于分布式系统中的节点之间存在可能故障和恶意行为的情况。 Golang语言有以下特点适合实现PBFT共识算法: 1. 并发性能强:Golang通过Goroutine和信道(Channel)实现了高效的并发,能够并行处理多个请求和节点之间的通信。这使得Golang非常适合处理PBFT算法中节点之间的消息传递和状态更新。 2. 跨平台支持广泛:Golang语言具有很好的跨平台支持,可以轻松部署在各种操作系统上。这对于实现一个可靠的共识算法来说非常重要,因为共识算法涉及到多个节点的交互和协同工作。 3. 内置网络库强大:Golang提供了内置的网络库,例如net包和http包,可以方便地实现节点之间的网络通信和消息传递。 4. 代码可读性好:Golang语言具有简洁的语法和良好的代码结构,使得代码易于阅读和理解。这对于共识算法这样复杂且关键的系统来说是至关重要的。 因此,使用Golang语言实现PBFT共识算法是非常可行的。开发者可以利用Golang的并发特性、跨平台支持和丰富的网络库进行快速而可靠的开发,以实现一个高性能和鲁棒的PBFT共识算法
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值