PBFT共识算法

概述

Practical Byzantine Fault Tolerance: PBFT,是联盟币的共识算法的基础。实现了在有限个节点的情况下的拜占庭问题,有3f+1的容错性,并同时保证一定的性能。

容错率

  • raft算法的的容错只支持容错故障节点,不支持容错作恶节点,所以容错率高,过半节点正常即可
  • PBFT算法可以容忍小于1/3个无效或者恶意节点
    作恶节点:除了可以故意对集群的其它节点的请求无响应之外,还可以故意发送错误的数据,或者给不同的其它节点发送不同的数据,使整个集群的节点最终无法达成共识,这种节点就是作恶节点。

角色

Primary节点和普通节点,PBFT系统的Primary是轮流当选的,这和zab、raft不一样

  • 主节点 p = v mod |R|
  • p:主节点编号
  • v:视图编号
  • |R|节点个数

Primary角色分析

Primary节点的作用:

  1. 正常工作时,接收客户端的事务请求,验证request身份后,为该请求设置编号,广播pre-prepare消息
  2. 新Primary当选时,根据自己收集的View-Change消息,发送View-New信息,让其它节点同步数据
  3. Primary与所有的其它节点维系心跳

Primary节点地位和follower节点一样,并没有什么特权

  1. 如果Primary宕机,会因为心跳超时,而触发重新选举,保证系统运行稳定
  2. 如果Primary恶意发送错误编号的消息,那么会在后续的操作中,被follower察觉,因为 prepare和commit阶段都是会进行广播的,一旦不一致,view-change
  3. 如果Primary不发送接收到的request,client在超时未回复时,会重发request到所有的replica,小弟们发现primary竟然私藏消息,view-change
  4. 如果Primary节点篡改消息,因为有Request里面有data和client的签名,所以primary无法篡改消息,其它replica会先验证消息的合法性,否则丢弃,view-change
    综上所述,限制了权限的Primary节点,如果宕机、或者不发生消息、或者发送错误编号的消息、或者篡改消息,都会被其它节点感知,并触发view-change。

PBFT工作正常的详细流程

客户端发起请求-->转发请求到primary-->primary生成proposal-->primary广播proposal-->所有节点复制proposal并广播-->复制过半节点完成-->广播commit节点-->commit过半节点完成-->应用状态机-->反馈客户端-->客户端统计f+1个反馈消息-->交易完成

  1. 系统根据机器编号顺序轮流选举出一个primary,primary初始化时发出View-new消息,同步所有节点的数据
  2. Client发起请求转发给primary,primary验证通过后,广播这个请求,发起pre-prepare消息给所有的follower节点,并且自己也保存这个request
  3. 所有的follower收到pre-prepare消息后,第一步是进行校验,包括数据的顺序是否正确,操作的先后有序性,以及交易是否有效比如签名。(防止客户端造假或者primary节点篡改造假)
  4. follower验证正确之后,写到自己的磁盘里,然后广播Prepare消息,并且自己也进入Prepare阶段
  5. 所有节点统计针对某个Request的Prepare消息,当统计结果超过2f节点时,表明大部分节点已经完成了持久化,则自己进入commit阶段
  6. 广播 commit 消息,并且统计收到的commit 消息的数量,当超过2f节点都发出commit的消息时
  7. 该节点完成commit阶段,写入数据(该操作已经完成2/3共识了),运用自己的状态机,更新 stable checkpoint,缓存该客户端最后一次的请求,并且反馈给客户端
  8. 当客户端统计反馈的节点超过f个时,表示交易已经被大部分节点确认了,交易成功。如果超时还不成功,则向所有的replica广播这个request

解释:

  1. 为什么客户端收到f+1个确认时,交易就成功了?
    因为默认问题节点为f,那么f+1个确认节点中,肯定有1个是诚实的节点,只要有1个诚实的确认消息,则交易成功,因为1个诚实的消息必须是2f+1个节点都commit操作成功了,才可能有这个1个最终确认消息的。所以为了提升交易处理的速度,只要有f+1个确认反馈,就可以表示交易成功。

客户端Client发起请求

  1. 客户端 c 通过向副本多播一条<REQUEST,o,t,c>到系统中
  2. 副本对Request进行身份验证
  3. 验证成功,则接受请求并将其添加到它们的日志中,请求执行使用request中的时间戳进行排序执行
  4. 副本直接将请求的回复发送给客户端
  5. 客户端在接受结果 r 之前,等待一个来自不同副本的有 f + 1 个带有有效 MACs 的以及相 同的 t 和 r 的 weak certificate
  6. 如果客户端没有足够迅速的收到一个 reply certificate,则会重新发送请求。如果请求已被处理,则副本只是重新发送回复;副本记住他们发送给每个客户端的最后一个回复消息以 启用此重传

客户端请求消息:客户端直接向Primary节点发起一个请求 : 消息的格式<REQUEST, o, t, c>

  • o: 请求的具体操作,operation
  • t: 请求时客户端追加的时间戳,time,这里面追加的是client的时间戳,会在后面的时候,客户端的请求做时间戳排序,结合请求编号一起,保证消息的有序性(不仅仅是写操作,还有读写操作)
  • c:客户端标识,clientID,其中 c + t 就是requestID
  • REQUEST: 包含消息内容m,以及消息摘要d(m)。客户端对请求进行签名。

服务端在执行request时会进行签名验证,因为PBFT应用的是联盟链,而不是私链,所以要对操作者的身份进行校验,比如A发起一笔转账,则服务端需要check是不是A发起的转账,防止盗刷

服务端回复消息:<REPLY, v, t, c, i, r>

  • REPLY,消息类型为回复客户端
  • v,当前view
  • t,c 哪个client的时间戳为t的回复(而不是通过zxid,是通过时间戳,相当于requestID)
  • i 当前node编号
  • r 操作结果,还必须有server i的签名,客户端要验证的,防止网络拦截和欺诈

消息

  • 消息的类型(pre-prepare、prepare、commit)

  • View(类似于term)

  • n(类似于index)

  • d(交易的详细信息)

  • m(交易的签名)

  • i(节点的编号)

  • checkpoint :节点参数,该节点最新的proposal编号

  • stable checkpoint:系统参数,该系统中,最新的超过2f节点commit过了的proposal的编号。可以减少内存的占用,已经2f+1确认过的操作,就最终确认了,后续不需要操作了,可以从内存中移除了。

重新选举 viewChange

当普通节点感知到primary异常的时候,触发viewchange,重新选举必须要有2f+1个节点都confirm(VIEW-CHANGE)了,发起重选才生效,一旦超过2f节点都发起VIEW-CHANGE消息,则选举结束,p =v+1 mod |R|节点当选为new Primary。并且new primary会根据自己统计的VIEW-CHANGE的内容,生成并广播NEW-VIEW消息,其它节点验证之后,开始新的view

<VIEW-CHANGE, v+1, n, C, P, i>消息

  • v+1 :新的view编号
  • n是最新的stable checkpoint的编号
  • C是2f+1验证过的CheckPoint消息集合
  • P是当前副本节点未完成的请求的PRE-PREPARE和PREPARE消息集合
    新的主节点就是 newPrimary = v + 1 mod |R|。当newPrimary收到2f个有效的VIEW-CHANGE消息后,向其他节点广播NEW-VIEW消息

<NEW-VIEW, v+1, V, O>

  • V是有效的VIEW-CHANGE消息集合
  • O是主节点重新发起的未经完成的PRE-PREPARE消息集合

未完成的PRE-PREPARE消息集合的生成逻辑:

  1. 选取V中最小的stable checkpoint编号min-s,选取V中prepare消息的最大编号max-s。
  2. 在min-s和max-s之间,如果存在P消息集合,则创建<<PRE-PREPARE, v+1, n, d>, m>消息。否则创建一个空的PRE-PREPARE消息,即:<<PRE-PREPARE, v+1, n, d(null)>, m(null)>, m(null)空消息,d(null)空消息摘要。

副本节点收到主节点的NEW-VIEW消息,验证有效性(各个replica都统计view-change的个数),有效的话,进入v+1状态,并且开始O中的PRE-PREPARE消息处理流程。

特殊情况:
那么如果一半的节点和primary网络分区了,那也无法发起重选。
同时primary也执行不了新的操作,因为新的消息有一半节点收不到,整个集群陷入瘫痪状态。所以primary也应该和zab一样,具备自我检测超时,超过一定个数的ack缺失时,触发重新选举。

Raft Vs PBFT

  1. Raft系统中leader拥有最高权限,follower如果和leader数据不一致,那么必须删除自己的数据,保持和leader一致

  2. PBFT中,Primary向我发送命令时,当我认为老大的命令是有问题时,我会拒绝执行。并且很有可能会触发view-change。就算我认为老大的命令是对的,我还会问下团队的其它成员老大的命令是否是对的,只有大多数人 (2f+1) 都认为老大的命令是对的时候,我才会去执行命令

PBFT的特点

  1. 客户端事务请求的严格有序性
    request里面包含了时间戳,request在服务端执行的时候,按照时间戳进行排序执行。而zab协议、raft协议都是按照先到先执行的有序性(服务端),但是PBFT却能按照Client的有序性。即使网络问题,先发起的请求晚于后发起的请求抵达服务端,服务端也不会打乱执行的顺序,PBFT是更严格的操作有序性。这也提高了系统的复杂度。

  2. 性能尚可
    PBFT 算法通信复杂度 o(n^2),因为系统在尝试达成状态共识时,涉及到N个几点都需要广播N-1个其它节点。而在没有作恶节点的zab、raft系统中,通信复杂度 O(N)

参考

美图架构师 讲PBFT 和Raft区别
https://zhuanlan.zhihu.com/p/35847127

原始论文的地址
http://pmg.csail.mit.edu/papers/osdi99.pdf

论文翻译中文版
https://blog.csdn.net/DeveloperRen/article/details/82771710

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容

  • 算法   Our algorithm is a form of state machine replication...
    小谁是谁阅读 1,481评论 0 2
  • 论文: Practical Byzantine Fault Tolerance PBFT及其变种在区块链共识算法中...
    柳正来阅读 12,985评论 0 6
  • 【幸福男孩,郏县,张易,坚持分享第164天,2018.4.28】 人们都认为猪是又懒又脏又贪吃的东西,其实,猪可是...
    简单男孩阅读 662评论 0 1
  • 【持枢拆古文】|《汉书》《资治通鉴》 原文 乙巳,皇后陈氏废。 既而以子夫为夫人,青为太中大夫。 立卫夫人为皇后,...
    持枢君阅读 321评论 0 1
  • 前几天,朋友忽然在电话里说,她想离婚,已经搬离开家。 工作不忙时,她总是懒懒地磨蹭到中午才起床,细心地化好妆,头发...
    米灿灿88阅读 211评论 0 2