精华内容
下载资源
问答
  • 基于源路由容错算法的接口标记容错路由算法
  • 拜占庭容错算法是去中心化的经典共识算法,又名PBFT算法,该算法曾经获得2002年图灵奖。
  • 区块链是一个分布式账本系统,参与者通过点对点网络连接,所有消息都通过广播的形式来 发送。实用拜占庭容错算法详解,包括拜占庭将军问题、三阶段过程、主节点是拜占庭节点问题、以及视图切换机制。
  • 小蚁区块链-拜占庭容错算法.pdf
  • 基于融合树的事件区域检测容错算法
  • 实用拜占庭容错算法

    千次阅读 2021-05-17 14:11:46
    实用拜占庭容错算法 作者:段玉龙2018201112 、朱江2018201116、卢薪丞2017201116 背景提出——拜占庭将军问题 拜占庭将军问题是由Leslie Lanport提出的分布式对等网络通信融资问题,那么它具体是什么呢,我们来...

    哈尔滨工程大学计算机学院2021年区块链技术课程

    实用拜占庭容错算法

    作者:段玉龙2018201112 、朱江2018201116、卢薪丞2017201116

    背景提出——拜占庭将军问题

    拜占庭将军问题是由Leslie Lanport提出的分布式对等网络通信融资问题,那么它具体是什么呢,我们来打个比方,如果你是一支拜占庭军队的将军,并且准备攻击一座敌方城市,在城市周围有几支有其他将军领导的军队,如果大家一起合作进攻,那么一定会大获全胜。但是如果大家各顾各,零散攻击,那么会导致进攻失败。这个时候作为将军的你,决定在傍晚攻击。在那个时期你并没有办法通过电话商量,也没有办法发送可能被敌方看到的信号弹,来联系所有的将军,让大家达成共识一起发动傍晚的攻击。所以您只能通过传令兵来传递信息。那么问题来了,如果传令兵在路途中被杀害怎么办,被敌方逮捕换成假信息怎么办,再者其他将军又如何判定你的传令兵递送的消息就是你的消息呢?更要命的是如果其中有叛军故意发送同意攻击的信息,但是实际进攻中不出兵又怎么办,这样各支军队的一致协同就遭到了破坏,所以你该怎么确保所有的军队会达成共识,并且同时出击呢?这个就是困扰了近千年的拜占庭将军问题,他问题的核心就是:单独个体如何可以不带任何条件地相信彼此。

    由此引出拜占庭容错算法。

    BFT拜占庭容错系统

    拜占庭容错技术被设计用来处理异常行为(包括硬件错误、网络拥塞、以及恶意攻击),被设计用来处理这些异常行为。发生故障的节点是拜占庭节点,正常的节点为非拜占庭节点。

    但是拜占庭容错算法(BFT)在实用中有很多不便之处, 早期提出的能解决拜占庭问题的算法(包括随拜占庭问题论文提出来的两种原生算法),要么仅仅停留在展示算法的理论可能性阶段,而实用性不高,要么就假设算法的使用环境为同步系统,而真实生产中的信息系统往往是异步的,例如互联网。由此衍生出了实用拜占庭容错算法(PBFT),它也是庭容错算法(BFT)下的一个分支。下面会详细讲解实用拜占庭容错算法(PBFT)。

    实用拜占庭容错算法(PBFT)

    PBFT算法前提,采用密码学算法保证节点之间的消息传送是不可篡改的。

    PBFT容忍无效或者恶意节点数:f,为了保障整个系统可以正常运转,需要有2f+1个正常节点,系统的总节点数为:|R| = 3f + 1。也就是说,PBFT算法可以容忍小于1/3个无效或者恶意节点。
    PBFT是一种状态机副本复制算法,所有的副本在一个视图(view)轮换的过程中操作,主节点通过视图编号以及节点数集合来确定,即:主节点 p = v mod |R|。v:视图编号,|R|节点个数,p:主节点编号。

    PBFT算法每个客户端请求需要经过5个阶段,主要是①request——请求②pre-Prepare——序号分配③Prepare——交互④commit——序号确认⑤reply——响应

    以下详细说明一下这五个阶段流程:

    1. Request:

    客户端c向主节点p发送<REQUEST, o, t, c>请求。o: 请求的具体操作,t: 请求时客户端追加的时间戳,c:客户端标识。REQUEST: 包含消息内容m,以及消息摘要d(m)。客户端对请求进行签名。

     

    1. Pre-Prepare:

    主节点收到客户端的请求,需要进行校验客户端请求消息签名是否正确。校验的步骤如下

     

    非法请求丢弃。正确请求,分配一个编号n,编号n主要用于对客户端的请求进行排序。然后广播一条<<Pre-Prepare, v, n, d>,  m>消息给其他副本节点。v:视图编号,d客户端消息摘要,m消息内容。<Pre-Prepare, v, n, d>进行主节点签名。n是要在某一个范围区间内的[h, H]。

     

    1. Prepare:

    副本节点i收到主节点的Pre-Prepare消息,需要进行以下校验:

     

    a. 主节点Pre-Prepare消息签名是否正确。

    b. 当前副本节点是否已经收到了一条在同一v下并且编号也是n,但是签名不同的Pre-Prepare信息。

    c. d与m的摘要是否一致。

    d. n是否在区间[h, H]内。

    非法请求丢弃。正确请求,副本节点i向其他节点包括主节点发送一条<Prepare, v, n, d, i>消息, v, n, d, m与上述Pre-Prepare消息内容相同,i是当前副本节点编号。<Prepare, v, n, d. i>进行副本节点i的签名。记录Pre-Prepare和Prepare消息到log中,用于View Change过程中恢复未完成的请求操作。

     

    1. Commit

    主节点和副本节点收到Prepare消息,需要进行以下校验:

     

    a. 副本节点Prepare消息签名是否正确。

    b. 当前副本节点是否已经收到了同一视图v下的n。

    c. n是否在区间[h, H]内。

    d. d是否和当前已收到Pre-Prepare中的d相同

    非法请求丢弃。如果副本节点i收到了2f+1个验证通过的Prepare消息,则向其他节点包括主节点发送一条<Commit, v, n, d, i>消息,v, n, d,  i与上述Prepare消息内容相同。<Commit, v, n, d, i>进行副本节点i的签名。记录Commit消息到日志中,用于View Change过程中恢复未完成的请求操作。记录其他副本节点发送的Prepare消息到log中。

     

    1. Reply:

    主节点和副本节点收到Commit消息,需要进行以下校验:

     

    a. 副本节点Commit消息签名是否正确。

    b. 当前副本节点是否已经收到了同一视图v下的n。

    c. d与m的摘要是否一致。

    d. n是否在区间[h, H]内。

    非法请求丢弃。如果副本节点i收到了2f+1个验证通过的Commit消息,说明当前网络中的大部分节点已经达成共识,运行客户端的请求操作o,并返回<Reply, v, t, c, i, r>给客户端,r:是请求操作结果,客户端如果收到f+1个相同的Reply消息,说明客户端发起的请求已经达成全网共识,否则客户端需要判断是否重新发送请求给主节点。记录其他副本节点发送的Commit消息到log中。

     

    (流程示意参考图)

    总结

    PBFT算法由于每个副本节点都需要和其他节点进行P2P的共识同步,因此随着节点的增多,性能会下降的很快,但是在较少节点的情况下可以有不错的性能,并且分叉的几率很低,可以较好的解决拜占庭容错问题。

     

     

    参考文献:https://blog.csdn.net/jfkidear/article/details/81275974

    展开全文
  • 基于序贯概率映射的组合导航自适应容错算法
  • 针对无线传感器网络存在服务质量不高的问题,提出一种基于中值差值的分布式容错算法,建立一套能量有效的事件区域检测容错机制,该算法充分利用传感器节点的空间相关性,融合各邻居节点的中值信息,对中心节点的最终...
  • 一种用于区块链的拜占庭容错算法
  • 关于区块链技术原理应用实践的详细介绍 一种用于区块链的拜占庭容错算法.pdf
  • 拜占庭容错算法的新发展——GBFT 本文为哈尔滨工程大学计算机学院2021年区块链技术课程,由2018201319 李合尧同学查阅相关博客以及论文进行的总结描述,由于第一次发表学术文章,才疏学浅,若有疏漏以及版权问题还请...

    基于通信时间分组的 PBFT 算法——GBFT

    本文为哈尔滨工程大学计算机学院2021年区块链技术课程,由2018201319 李合尧同学查阅相关博客以及论文进行的总结描述,第一次发表学术文章,才疏学浅,若有疏漏以及版权问题还请指出,不胜感激。

    1.背景

    拜占庭容错算法(Byzantine Fault Tolerant)是面向拜占庭问题的容错算法,解决的是在网络通信可靠,但节点可能故障和作恶情况下如何达成共识,但是该算法复杂度为O( n ^ (f+1) ),在实际的分布式应用系统中无法应用。

    在此之后也出现了很多的改进工作,但长期以来,拜占庭容错算法都存在运行过慢,复杂度太高,不能够很好的应用到实际。直到1999年实用型容错算法的提出,将算法的复杂度降低到了O(n2),解决了缺少可信度的中央节点和可信任下的通道情况下,分布在网络各个节点如何达成共识的问题,使得可以在实际系统应用中解决拜占庭问题。

    但是该算法的复杂度还是太高,以及该算法在实现节点之间的协商状态一致时需要经过三阶段的节点通信,两次大量的全网节点消息广播占用了大量的通信资源,造成了严重的通信资源浪费,同时其可扩展性非常差,无法应用到大规模区块链系统,PBFT算法还不能够动态的感知结点的加入和退出,浪费了新加入节点的资源。对于PBFT算法存在的缺点,在后续的发展中大多数算法都采用对节点状态的进行分组,通过降低全局共识的节点数量来减低消息交互的次数,从而来改善PBFT算法的缺点,如基于信用将节点分级,或者将节点分为几个状态,形成生命周期,使节点能够动态地进入和退出等等。

    在本文中讲述的GBFT算法是根据节点之间的通行时间进行分组分层的方法进行共识,以及动态的感知节点的加入和离开,使资源利用达到最大化。在本文中主要从如何对节点进行分组分层以及分组分层后节点之间如何进行共识来讲述GBFT算法。

    2. 节点之间的分组分层

    最优分组和平均时延的估计是为分组提供依据,然后在讲述了分组的具体步骤以及需要重新分组的情况。

    2.1 最优分组

    主要是在最优分组之时确定分组的组数以及组内的人数。
    ** 方法**:只考虑平均时延的情况下,使用共识过程中的交互信息数计算出最优分组,主要由三个方面组成,即主节点(主节点的确定:根据试图编号v,当前区块的高度h以及参与共识的节点总数n,利用(h+v)mod n公式确定)发起题案发送消息数,以及组内准备和组内确认发送的消息数,全局共识准备与全局共识确认发送的消息数,然后利用在这里插入图片描述,当其等于0时求出使得交互信息数最少时分组个数以及组内成员数量。

    2.2平均时延估计

    该阶段是为后面具体分组时选取组内成员提供标准,将分散的节点分为多个通行时间基本一致的组,各个节点根据平均时延分别统计在平均时延内的节点编号数量,节点编号,通信时间,并升序排列通信时间。主要是建立各个节点的通信时间邻接表,然后根据通信时间领接表得出平均时延。
    通信时间邻接表的建立:假设在这个区块链网络初始启动时,全网节点都处于孤立节点状态,主要分为下面几个步骤:
    1.首先给所有参与共识的副本节点用1到n进行编号ID,然后从ID最小节点Ri的开始向比自己ID最大的节点Rj发送探测信息,其中包括节点自身信息,以及请求计算通信时间的信息状态,以及发送消息时区块链网络上的时间t1。
    2.其他节点Rj在收到信息后,记录收到信息时区块链网络上的时间t2,计算两时间之差T1ij,再返回一个消息给Ri,其中包括对消息进行回复的状态信息,自身节点信息,T1ij,t2。
    3. Ri在收到返回的消息后也会根据t1,t2算出之差T2ij,再根据两时间算出平均值,然后将其记录在共识节点组成的邻接表中,完成后,在之前的i+1个节点以及后一个节点发送一个包含更新后的通信邻接时间表以及节点自身信息的信息,
    4. 节点Ri+1保存Ri发送的消息后,开始重复Ri的操作,直到n-1各节点将更新后的邻接表广播后,区块链网络建立由各个节点组成的通行时间表,各个共识节点 Ri 根据邻接表的值。然后根据在这里插入图片描述公式得出平均通信时延 。

    2.3形成分组

    该阶段是根据主节点在给定的共识时间间隔内,发起一轮新的共识,然后主节点启动分组协议,然后开始进行分组。其主要步骤为:
    1.确定组数和组内人数:根据全网的共识节点的数目以及通过上述所说的最优分组的方法计算出最优分组时的组数以及组内人数。
    2.确定拟组长节点以及选取组员:所有满足其平均时延的节点编号数量大于最有分组的组内数量的节点都为拟组长节点,其根据邻接表选取自己的组员,向选择的组员发送包含节点自身信息,组长节点状态信息的信息。
    3.组员返回信息:组员节点接收到拟组长节点发送的信息后,想起返回包含自身基本信息,非组长节点状态信息,ID信息的信息。
    选取组员的规则:
    1.平均时延内节点编号数量最少的拟组长节点作为一个选取组员的节点,若多个相同则ID号最小的开始。
    2.当拟组长节点选取了的通信时间在平均时延之内的节点不能再被继续选取
    3.当拟组长节点的邻接表内在平均时延下的节点少与需要成组的人数,则依次顺延至下一个拟节点,若遍历完整个拟节点数后还没有找到则在邻接表中找前面满足对应成组的个数的结点。
    分组的最终结果是形成以组长节点为中心的多个圆簇,每个组长节点负责维护组内成员,如下图所示:
    在这里插入图片描述

    2.4 需重新分组的情况

    并不是每次共识都会发起分组协议,那样会大大降低效率,同时也没有必要,需要重新分组的情况主要分为两部分:
    1.拜占庭节点的增多:拜占庭节点简单说就是出错了的结点,每个组设立一个拜占庭区,通过组内之间的共识,组内之间的每个节点都知道那些节点为拜占庭结点,然后将其加入拜占庭区中,当拜占庭区中的节点个数多余f1时,则该组所有的节点不再参与组内共识和全局共识,组内非拜占庭结点向区块链网络中的其他节点发送该组已经出错的信息,然后其余节点将改组的整组成员添加至拜占庭区,当拜占庭区内的组数多于f2时是则需要重新分组。
    2.节点的加入:每当有新的节点加入时,主节点都会发起新一轮的分组。当有新的节点加入时,其会想其他节点发送探测信息,其他节点收到信息后返回通信时间邻接表,新节点同时计算平均通信时延以及更新通信时间邻接表,再将其发送至区域链网络所有共识的节点。

    3. 共识

    在整个区块链网络中,所有的共识节点都有可能是最终的记账节点,所以不仅参与共识也要保存区块链数据。当收到交易数据,所有共识节点验证交易合法性,将通过验证的交易数据添加至自己的内存中并根据前一区块的哈希索引、版本号、区块高度等信息构造一个候选区块,并广播至其他共识节点,不合法则直接丢弃,这确保了只有有效的交易才能在区块链网络中传播。

    3.1共识步骤

    共识主要分为6个步骤:
    1.Consensus-Proposal阶段:主节点P向所有副本节点发起共识提案消息,其余节点在接受到信息后判断其是否正确,若正确则进入组内共识,错误或者超过共识间隔时间后仍为发起共识提案,则进行视图变更。
    2.Grouped-Prepare阶段:各个组的节点向同组的节点发送组内共识的准备消息,当节点收到该组2 f1+1个不用节点消息且消息正确则进入确认阶段。
    3.Grouped-Commit阶段:同一组的各个节点互相发送确认消息,若接收到2 f1+1来自不同节点的消息以及都正确时则进入全局共识。
    4.Global-Prepare阶段:所有组长节点参与全局共识,组长节点之间发送准备消息,当每个组长节点收到2 f2+1个来自不同的组长节点的消息且都正确时则进入全局确认阶段。
    5.Global-Commit阶段:各个组长节点之间相互发送确认消息,当每个组长节点收到2 f2+1个来自不同的组长节点的消息且都正确时,即认为共识达成,可以发布来自主节点提案的区块。
    6.其余节点根据最新的区块,将自己内存中的与区块 中相同的交易删除,同时开始构造新的区块,准备下一轮的共识。
    算法共识流程图如下:
    在这里插入图片描述

    3.2 邻接表的更新

    邻接表更新除了节点的加入和退出外,组内共识和全局共识动态更新部分的邻接表的通信时间。组内共识以及全局共识的消息都包含时间戳,根据通信时间的计算方法,每次收到共识阶段内的消息后自动计算传播时间并记录,待一轮共识完成后,将所有收集到的消息的通信时间累加并取平均值,将计算出的值填入邻接表的对应位置,完成邻接表的更新。

    3.3组长节点的轮换

    组长节点并不是选好了就不变的,在GBFT中采用评分的方式来轮换组长节点,开始是各个节点的评分为0,在共识阶段中,产生区块的节点评分加一,若主节点被节副点怀疑而引发视图变更,若成功,则主节点评分减二,副节点加一,然后要根据评分建立忠诚度表,其是利用公式在这里插入图片描述,c的计算是综合了score与担任组长次数t的结果,平衡每个节点成为组长节点的几率,避免分数高的节点长期担任组长。 α 与 β 为调节系数。c的值最高的成为下一轮次的组长节点。

    3.4视图变更

    当其他节点怀疑主节点或者在共识间隔时间内为发起新的共识,则由怀疑主节点的节点或随机选取的节点发起视图变更消息,具体的变更流程如下:
    1.怀疑主节点的结点或者随机选取的结点向其他节点发送变更视图的消息。
    2.其余节点收到消息后验证视图变更消息是否正确,若为真,则拒绝主节点的共识提案并向全网广播视图变更确认消息。
    3.任何一个节点如果收到来自其他(2 n-1)/3条图变更确认消息后,视图变更得到确认,更改新的视图 。新的主节点开始下一轮的共识提案。

    展开全文
  • PBFT实用拜占庭容错算法深入详解

    千次阅读 2018-08-14 19:12:23
    PBFT即实用拜占庭容错算法,由Miguel Castro和Barbara Liskov在1999年提出,可以在作恶节点少于三分之一的情况下,保证系统的正确性(避免分叉)。与原始的BFT算法相比,算法复杂度从指数级降低到了多项式级,从而...

    PBFT即实用拜占庭容错算法,由Miguel Castro和Barbara Liskov在1999年提出,可以在作恶节点少于三分之一的情况下,保证系统的正确性(避免分叉)。与原始的BFT算法相比,算法复杂度从指数级降低到了多项式级,从而使得BFT算法的实际应用成为可能。实际上,Tenermint就是PBFT的一个简化版本的实现。

    基本概念

    首先了解一下几个基本概念:(从区块链的视角)

    • replica:即区块链节点,提供“副本复制”服务
    • client:向primary发起请求的客户端节点,在区块链中往往跟primary合二为一
    • primary:区块发起者,在收到请求后生成新区块并广播
    • backup:区块验证者,在收到区块后进行验证,然后广播验证结果进行共识
    • view:一个primary和多个backup形成一个view,在该view上对某个区块进行共识
    • sequence number(n):由primary指定的一个数字,可以理解为区块高度
    • checkpoint:如果某个sequence number对应的区块收到了超过2/3的确认,则称为一个checkpoint

    另外,primary是所有节点轮流做的,每个view上都会选出一个新的primary。

    三阶段协议

    三阶段协议是PBFT的核心,参见下图:
    这里写图片描述

    从发起请求到最终收到reply,中间的共识过程需要经过3个阶段:

    • pre-prepare:primary收到请求,生成新区块并广播
    • prepare:所有replica收到区块后,广播区块验证结果,同时等待接收超过2/3的节点的广播
    • commit:收到2/3的节点广播或者超时后,再次发送广播,同时再次等待接收超过2/3的节点的广播

    这里的逻辑有点绕:
    第一次等待超过2/3的节点广播,是为了确认“已经有超过2/3的节点收到区块了”。但是这只是你自己知道,别人并不知道啊,因此需要再发送一次广播,告诉别的节点“我已经确认有超过2/3的节点收到区块啦”。而第二次等待超过2/3的节点广播,则是为了确认“已经有超过2/3的节点确认(有超过2/3的节点收到区块啦)”,此时说明已经达成共识,可以把该区块写到链上了。

    PBFT状态机

    这个原文是没有图的,只能根据文字描述自行理解,还是挺复杂的:

    这里写图片描述

    图中的圆角矩形表示状态,六边形表示等待阶段,绿线代表正常流程,红线代表异常流程。下面一个一个的来介绍:

    • wait request
      • 即等待请求状态,所有节点初始均处于该状态
      • primary收到REQUEST消息后,会转换到pre-prepare状态
      • backup收到区块后,会转换到prepare状态
    • pre-prepare
      • 这个状态是primary专属的,primary生成区块并广播PRE-PREPARE消息后,转换到prepare状态
    • prepare
      • 进入该状态后,广播PREPARE消息,并等待2f+1个节点确认
    • wait for 2f+1 prepare
      • 如果等到了2f+1个节点确认(accept或reject),转换到commit状态
      • 如果超时,转换到view change状态
    • commit
      • 进入该状态后,广播COMMIT消息,并等待2f+1个节点确认
    • wait for 2f+1 commit
      • 如果等到了2f+1个节点确认(accept或reject),发送REPLY消息,转换回wait request状态
      • 如果超时,转换到view change状态
    • view change
      • 进入该状态后,广播v+1的VIEW-CHNAGE消息,等待接收2f个节点的VIEW-CHANGE消息
    • wait for 2f view change
      • 这个状态比较复杂,可以分为以下4种情形:
        • 收到了2f个节点的VIEW-CHANGE消息,并且是新的primary,广播NEW-VIEW消息,并转换到pre-prepare状态
        • 收到了2f个节点的VIEW-CHANGE消息,并且是backup,转换到wait request状态
        • 接收超时,重新回到view change状态,广播v+2的VIEW-CHANGE消息
        • 在收到2f个节点的VIEW-CHANGE消息之前,收到了NEW-VIEW消息,则转换到prepare状态

    需要注意的是,如果接收到了NEW-VIEW消息,则表示当前view未达成共识,需要在更高层的view上完成共识。因此,不管当前处于哪个阶段,都需要重新回到prepare状态。

    数据结构

    接下来就是介绍一下相关的数据结构了,主要是状态和消息。

    State

    这里写图片描述

    节点的状态主要包含三部分:

    • 世界状态(即最新区块信息)
    • 消息日志
    • 当前view

    Three Phase Protocol

    这里写图片描述

    这里列出了三阶段协议相关的消息结构,其中PRE-PREPARE消息包含新生成的区块,其他消息则主要包含一些id、sequence number、区块内容摘要和签名等信息。

    VIEW-CHANGE

    这里写图片描述

    VIEW-CHANGE消息包含的内容比较多:
    首先需要基于一个稳定的checkpoint,因此需要包含2f+1个CHECKPOINT消息以证明该checkpoint是有效的。
    然后,在该checkpoint之上的所有sequence number,都需要打包对应的PRE-PREPARE消息以及2f个PREPARE消息。

    NEW-VIEW

    这里写图片描述

    NEW-VIEW消息首先需要包含2f+1个VIEW-CHANGE消息,以证明确实有超过2/3的节点同意在更高的view上进行新一轮共识。
    然后,根据收到的所有VIEW-CHANGE消息中的checkpoint信息,找出最小值min_s和最大值max_s,打包该区间内的每一个sequence number对应的PRE-PREPARE消息。
    特别的,为了减少重复验证,如果在某个sequence number上从未进行过view change(即第一轮就达成了共识),则PRE-PREPARE中包含一个特殊的null请求的摘要信息。

    具体逻辑参见下图:
    这里写图片描述

    如果想要了解更多的算法细节,可以阅读论文原文:
    http://pmg.csail.mit.edu/papers/osdi99.pdf

    更多文章欢迎关注“鑫鑫点灯”专栏:https://blog.csdn.net/turkeycock
    或关注飞久微信公众号:
    在这里插入图片描述

    展开全文
  • 低成本列车组合定位系统容错算法设计帮助你理解容错方面的问题,很有帮助。
  • 针对执行器发生部分失效故障的空间机器人,提出一种基于比例因子识别的自校正反馈神经网络容错算法.首先,针对无故障系统设计一种常规的神经网络控制算法;然后,利用比例因子观测器对真实的比例因子进行识别;最后,将该...
  • 这是一篇关于多站无源跟踪系统容错算法的文章
  • 片上网络中的容错算法综述,罗莎莎,徐成,随着芯片集成度的不断提高,片上网络通信的可靠性面临诸多挑战,其独特的性能特点和技术要求,使得许多传统容错技术无法被直接应��
  • 基于子带位平面容错算法的应用基于子带位平面容错算法的应用
  • 这是一篇关于多机环境下的一种容错算法的文章
  • 算法高级(20)-集群容错算法

    千次阅读 2019-09-11 20:18:55
    一、集群容错场景 集群服务调用失败后,服务框架需要能够在底层自动容错容错策略很多,分别适用于不同场景。 在分布式服务框架中,业务消费者不需要了解服务提供者的具体位置,它发起的调用请求也不包含服务提供...

     一、集群容错场景

    集群服务调用失败后,服务框架需要能够在底层自动容错,容错策略很多,分别适用于不同场景。

    在分布式服务框架中,业务消费者不需要了解服务提供者的具体位置,它发起的调用请求也不包含服务提供者的具体地址信息。因此,某个服务提供者是否可用对消费者无关紧要,最终的服务调用成功才是最重要的。

    经过服务路由之后,选定某个服务提供者进行远程调用,但是服务调用可能出错,下面对可能的故障场景进行分析。

     1.1、通信链路故障

            这里的链路指的是消费者和服务提供者之间的链路(通常为长连接),可能导致链路中断的原因有
                1)通信过程中,对方突然宕机导致链路中断。
                2)通信过程中,对方因为解码失败等原因Rest掉连接,导致链路中断。
                3)通信过程中,消费者write SocketChannel发生IOException导致链路中断。
                4)通信过程中,消费者read SocketChannel发生IOException异常导致链路中断。
                5)通信双方因为检测心跳超时,主动close SocketChannel导致链路中断。
                6)通信过程中,网络出现闪断故障。
                7)通信过程中,交换机异常导致链路中断。
                8)通信过程中,消费者或者服务提供者因为长时间Full GC导致链路中断。
            无论哪种原因导致链路中断,都会导致本次服务调用失败。

        1.2、服务端超时

            当服务端无法再指定的时间内返回应答给客户端,就会发生超时,导致超时的原因主要有:
                1)服务端I/O线程没有及时从网络中读取客户端请求消息,导致该问题的原因通常是I/O线程被意外阻塞或者执行长周 期操作
                2)服务端业务处理缓慢,或者长时间阻塞,列如查询数据库,由于没索引导致全表查询,耗时较长。
                3)服务端发生长时间Full GC,导致所有业务线程暂停运行,无法及时返回应答给客户端。

        1.3、服务端调用失败

            有时会发生服务端调用失败,导致服务端调用失败的原因主要有如下几种:
                1)服务端解码失败,会返回消息解码失败异常。
                2)服务端发生动态流控,返回流控异常。
                3)服务消息队列积压率超过最大阈值,返回系统拥塞异常。
                4)访问权限校验失败,返回权限相关异常。
                5)违反SLA(Service-Level Agreement:服务等级协议)策略,返回SLA控制相关异常。
                6)其他系统异常。
            需要指出的是服务调用异常不包括业务方面的处理异常,例如数据库异常、用户记录不存在异常等。

    二、集群容错策略

     服务不同,容错策略也往往不同。下面看看集群容错和路由策略之间的关系。如图1-1所示:

     消费者根据配置的路由策略选择某个目标地址之后,发起远程服务调用,在此期间如果发生远程服务调用异常,则需要框架进行集群容错,重新进行选路和调用,集群容错是系统自动执行的,上层用户并不关心底层的服务调用过程。

        2.1、失败自动切换(Failover)

            服务调用失败自动切换策略指的是当发生RPC调用异常时,重新选路,查找下一个可用的服务提供者。

            服务发布的时候,可以指定服务的集群容错策略。消费者可以覆盖服务提供者的通用配置,实现个性化的容错策略。

            Failover策略的设计思路如下:消费者路由操作完成之后,获得目标地址,调用通信框架的消息发送接口发送请求,监听服务端应答。如果返回的结果时RPC调用异常(超时、流控、解码失败等系统异常),根据消费者集群容错的策略进行容错路由,如果是Failover,则重新返回到路由Handler的入口,从路由节点继续执行。选路完成之后,对目标地址进行对比,防止重新路由到故障服务节点,过滤掉上次的故障服务提供者之后,调用通信框架的消息发送接口发送请求消息。

            分布式服务框架提供Failover容错策略,但是用户在使用时需要自己保证用对地方,下面对应用场景进行总结:
                1)读操作,因为通常它是幂等的。
                2)幂等性服务,保证调用1次与N次效果相同。
            需要特别指出的是,失败重试会增加服务调用时延,因此框架必须对失败重试的最大数做限制,通常默认为3,防止无限制重试导致服务调用时延不可控。

        2.2、失败通知(Failback)

            很多业务场景中,消费者需要能够获取到服务调用失败的具体信息,通过对失败错误码等异常信息的判断,决定后续的执行策略,例如非幂等性服务调用。

            Failback的设计方案如下:服务框架获取到服务提供者返回的RPC异常响应之后,根据策略进行容错。如果是Failback模式,则不再重试其他服务提供者,而是将RPC异常通知给消费者,由消费者捕获异常进行后续处理。

        2.3、失败缓存(Failcache)

            Failcache策略是失败自动恢复的一种,在实际开发中应用场景如下:
                √ 服务状态路由,必须定点发送到指定的服务提供者。当发生链路中断、流控等服务暂时不可用时,服务框架将消息暂时缓存起来,等待周期T,重新发送,回到服务提供者能够正常处理该消息。
                 √ 对时延要求不敏感的服务。系统服务调用失败,通常是链路暂时不可用、服务流控、GC挂住服务提供者进程等,这种失败不是永久性的,他的失败是可预期的。如果消费者调用对时延不敏感,可以考虑使用自动恢复模式。既先缓存、再等待、最后重试。
                 √ 通知类服务。对服务调用的实时性不高,可以容忍自动恢复带来的时延增长。

            为了保证可靠性,Failcache策略在设计的时候需要考虑如下几个要素:

                  √ 缓存时间、缓存对象上限数等需要做出限制,防止内存溢出。
                  √ 缓存淘汰算法的选择,是否支持用户配置。
                  √ 定时重试的周期T,重试的最大次数等需要做出限制并支持用户指定。

        2.4、快速失败(Failfast)

            在业务高峰期,对于一些非核心的服务,希望只调用一次,失败也不再重试,为重要的核心服务节约宝贵的运行资源。此时快速失败是个不错的选择。

            快速失败策略设计简单,获取到服务异常之后,直接忽略异常,记录异常日志。

        2.5、容错策略扩展

            无论服务框架支持多少种容错策略,业务在实际使用过程中一定会有不适应的地方,通过开放容错策略接口的方式,可以支持用户自定义扩展容错策略。

            在集群容错设计的时候,需要考虑扩展性,主要从以下几方面进行设计:

                1)容错接口的开放。
                2)屏蔽底层细节,用户定制简单。
                3)配置应当支持扩展,不要让用户扩展服务框架Schema。

    三、Dubbo服务集群容错

    先来介绍一下Dubbo集群容错的所有组件。包含 Cluster、Cluster Invoker、Directory、Router 和 LoadBalance 等。

    集群工作过程可分为两个阶段,第一个阶段是在服务消费者初始化期间,集群 Cluster 实现类为服务消费者创建 Cluster Invoker 实例,即上图中的 merge 操作。第二个阶段是在服务消费者进行远程调用时。以 FailoverClusterInvoker 为例,该类型 Cluster Invoker 首先会调用 Directory 的 list 方法列举 Invoker 列表(可将 Invoker 简单理解为服务提供者)。Directory 的用途是保存 Invoker,可简单类比为 List<Invoker>。其实现类 RegistryDirectory 是一个动态服务目录,可感知注册中心配置的变化,它所持有的 Invoker 列表会随着注册中心内容的变化而变化。每次变化后,RegistryDirectory 会动态增删 Invoker,并调用 Router 的 route 方法进行路由,过滤掉不符合路由规则的 Invoker。当 FailoverClusterInvoker 拿到 Directory 返回的 Invoker 列表后,它会通过 LoadBalance 从 Invoker 列表中选择一个 Invoker。最后 FailoverClusterInvoker 会将参数传给 LoadBalance 选择出的 Invoker 实例的 invoker 方法,进行真正的远程调用。

    假设我们使用的是单机模式的Dubbo服务,如果在服务提供方(Provider)发布服务以后,服务消费方(Consumer)发出一次调用请求,恰好这次由于网络问题调用失败,那么我们可以配置服务消费方重试策略,可能消费方第二次重试调用是成功的(重试策略只需要配置即可,重试过程是透明的);但是,如果服务提供方发布服务所在的节点发生故障,那么消费方再怎么重试调用都是失败的,所以我们需要采用集群容错模式,这样如果单个服务节点因故障无法提供服务,还可以根据配置的集群容错模式,调用其他可用的服务节点,这就提高了服务的可用性。

    简单地说目前Dubbo支持的集群容错模式,每种模式适应特定的应用场景,可以根据实际需要进行选择。Dubbo内置支持如下6种集群模式:

    1、Failover Cluster模式

    配置值为failover。这种模式是Dubbo集群容错默认的模式选择调用失败时,会自动切换,重新尝试调用其他节点上可用的服务

    对于一些幂等性操作可以使用该模式,如读操作,因为每次调用的副作用是相同的,所以可以选择自动切换并重试调用,对调用者完全透明。

    可以看到,如果重试调用必然会带来响应端的延迟,如果出现大量的重试调用,可能说明我们的服务提供方发布的服务有问题,如网络延迟严重、硬件设备需要升级、程序算法非常耗时,等等,这就需要仔细检测排查了。

    例如,可以这样显式指定Failover模式,或者不配置则默认开启Failover模式,配置示例如下:

    <dubbo:service interface="org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService" 
        version="1.0.0" cluster="failover" retries="2" timeout="100" 
        ref="chatRoomOnlineUserCounterService" protocol="dubbo" >
        <dubbo:method name="queryRoomUserCount" timeout="80" retries="2" />
    </dubbo:service>

    上述配置使用Failover Cluster模式,如果调用失败一次,可以再次重试2次调用,服务级别调用超时时间为100ms,调用方法queryRoomUserCount的超时时间为80ms,允许重试2次,最坏情况调用花费时间160ms。如果该服务接口org.shirdrn.dubbo.api.ChatRoomOnlineUserCounterService还有其他的方法可供调用,则其他方法没有显式配置则会继承使用dubbo:service配置的属性值。

    2、Failfast Cluster模式

    配置值为failfast。这种模式称为快速失败模式,调用只执行一次,失败则立即报错

    这种模式适用于非幂等性操作,每次调用的副作用是不同的,如写操作,

    比如交易系统我们要下订单,如果一次失败就应该让它失败,通常由服务消费方控制是否重新发起下订单操作请求(另一个新的订单)。

    3、Failsafe Cluster模式

    配置值为failsafe。失败安全模式,如果调用失败, 则直接忽略失败的调用,

    而是要记录下失败的调用到日志文件,以便后续审计

    4、Failback Cluster模式

    配置值为failback。失败自动恢复,后台记录失败请求,定时重发。

    通常用于消息通知操作。

    5、Forking Cluster模式

    配置值为forking。并行调用多个服务器,只要一个成功即返回

    通常用于实时性要求较高的读操作,但需要浪费更多服务资源。

    6、Broadcast Cluster模式

    配置值为broadcast。

    广播调用所有提供者,逐个调用,任意一台报错则报错(2.1.0开始支持)。

    通常用于通知所有提供者更新缓存或日志等本地资源信息。

    上面的6种模式都可以应用于生产环境,我们可以根据实际应用场景选择合适的集群容错模式。

    如果我们觉得Dubbo内置提供的几种集群容错模式都不能满足应用需要,

    也可以定制实现自己的集群容错模式,因为Dubbo框架给我提供的扩展的接口,只需要实现接口com.alibaba.dubbo.rpc.cluster.Cluster即可。

    四、总结

    集群容错从功能上看很简单,设计也并不复杂,但是该特性却非常重要,相比于传统的RPC框架,分布式服务框架让用户

    开发变得更简单,体验也更好。从功能上看,服务框架需要提供更丰富、更粒度的功能和扩展点,这就是它相比于传统RPC框架

    最大的优势。


    我的微信公众号:架构真经(id:gentoo666),分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。每日更新哦!

    参考资料:

    1. https://blog.csdn.net/zhengzhaoyang122/article/details/80884535
    2. https://www.cnblogs.com/lykbk/p/sdsd435345454545.html
    展开全文
  • 容错算法 (Fault Tolerant)容错算法 (Fault Tolerant)
  • 一种用于片上网络的低延迟容错算法,罗莎莎,徐成,片上网络(NoC)是替代传统片上总线通信,用于解决在片上系统通信组件数量不断增长所来带来的一系列问题的可行方案。芯片集成度的
  • 一种用于片上网络的同步回溯容错算法,徐成,罗莎莎,片上网络(NoC)是替代传统片上总线通信,用于解决在片上系统通信组件数量不断增长所来带来的一系列问题的可行方案。芯片集成度的
  • 这是关于一篇超立方体中两种容错算法的改进的文章
  • PBFT(Practical Byzantine Fault Tolerance)实用拜占庭容错算法实用拜占庭容错系统(PBFT)降低了拜占庭协议的运行复杂度,从指数级别降低到多项式级别(Polynomial),使拜占庭协议在分布式系统中应用成为可能。...
  • 该文提出基于单站多站、时差和角度测量组合的容错跟踪算法。该算法假定系统被干扰工作时使用基于时差测量的跟踪方法, 而多站角度和单站角度跟踪方法作为备用, 通过对每个周期目标状态变量的检测, 判定是否需要切换为...
  • 从改进提议分布的成片野值容错能力入手,提出了基于残差正交判别的UPF容错滤波算法,该算法将残差正交判别法UKF的野值自适应性和粒子滤波的“适者生存性”有机地结合起来,通过非线性状态估计的实验,证实了这种新的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 80,149
精华内容 32,059
关键字:

容错算法