分布式系统-3-同步网络算法

本文深入探讨了分布式同步网络中的核心算法,包括广度优先搜索(BFS)、最短路径和最小生成树(MST),以及如何利用这些算法解决实际问题如广播、全局计算和领导选举。同时,介绍了Bellman-Ford算法解决带权网络的最短路径问题,以及SynchGHS算法构建最小生成树。
引言

上一篇文章讲了同步网络中的leader选举算法。考虑一个问题,当网络中有消息需要广播时,如果在网络中以最快的速度完成广播?或者如何计算图的直径?接下来就会一步一步解决这些问题

将在这篇文章中讲述分布式同步网络中广度优先搜索、最短路径和最小生成数算法。

广度优先搜索

利用广度优先搜索来构造方便用于广播通信的树,BFS树最小化最大通信时间

SynchBFS算法
  • 前提假设

    1. 假设进程有uid
    2. 不知道网络大小和直径
    3. 给定初始root i0i_0i0
  • 进程维护状态

    1. parentparentparent:记录进程的父节点是谁
    2. markedmarkedmarked:记录是否被标记
  • 算法流程

    • 选择一个节点作为初始节点,定为i0i_0i0,设置为已标记,i0i_0i0发送一条search消息到节点iiiout−nbrsout-nbrsoutnbrs
    • 对于任意一个节点,如果节点还未被标记,并且收到search消息,则它将自己标记,并且将发送search消息的节点设置为它的parent,然后发送search消息到它的out−nbrsout-nbrsoutnbrs
  • 算法图解

    • 初始化选择4(可以随意选择)为root节点i0i_0i0

      在这里插入图片描述

    • 第一轮search消息,4只有一个out−nbrsout-nbrsoutnbrs,所以只有一条消息,5被标记,其parent节点为4,红色箭头代表search消息

      在这里插入图片描述

    • 第二轮search消息,5有两个out−nbrsout-nbrsoutnbrs

      在这里插入图片描述

    • 第三轮,因为是分布式系统,所以进程2和进程6是同时进行的

      在这里插入图片描述

  • 复杂度分析

    • 时间复杂度:最多为daim轮,为图的直径,实际上可能更小,是i0i_0i0到它最远的节点
    • 通信复杂度:通信复杂度:图的边数,∣E∣|E|E
  • 如何确定child节点:双向网络中非常容易,child发送一条消息给parent。在单向网络中,需要间接节点将消息传递给它的parent节点,因此可以用SynchBFS算法实现这个过程,如果每一轮中一条链路只能发送一条消息,那这些消息可以合并成一条消息

    • 复杂度分析
      • 双向通信网络
        1. 时间复杂度:O(diam)O(diam)O(diam)
        2. 通信复杂度:O(∣E∣)O(|E|)O(E),因为child可以直接发送消息给parent,因此总消息数为2⋅∣E∣2\cdot|E|2E
      • 单向通信网络
        1. 时间复杂度:O(diam)O(diam)O(diam),因为额外的消息可以并行发送
        2. 通信复杂度:O(diam⋅∣E∣)O(diam\cdot|E|)O(diamE),因为需要发送额外消息,因此每一轮中每条边都可能会发送消息,总共有diamdiamdiam轮,所以总消息最多为diam⋅∣E∣diam\cdot|E|diamE
  • SynchBFS算法终止

    • 核心思想:当消息传递到叶子节点时,叶子节点标记自己后,发送消息让parent知道其已经完成,当parent收到所有其子节点的确认完成消息后,parent发送消息给它的parent,循环这个过程直到确认消息到达root节点i0i_0i0
    • 复杂度分析
      • 双向通信网络
        1. 时间复杂度:O(diam)O(diam)O(diam),因为叶子节点返回确认完成消息是并行执行并且可以直接发送给parent,因此,时间最多为2⋅diam2\cdot diam2diam
        2. 通信复杂度:O(∣E∣)O(|E|)O(E)
      • 单向通信网络
        1. 时间复杂度:O(diam2)O(diam^2)O(diam2),因为在发送确认消息时,每一级parent都是执行一次SynchBFS算法,每一层级的节点不能并行执行,因为不能确定,该级的parent是否收到了所有child的确认消息,因child是通过间接的节点传递消息,因此可能绕了一个diam的路径,最多有diam个层级,因此时间复杂度为O(diam2)O(diam^2)O(diam2)
        2. 通信复杂度:O(diam2⋅∣E∣)O(diam^2\cdot|E|)O(diam2E),和确认child节点类似,虽然每个层级的节点确认完成消息不能并行执行,但是不同节点的确认可以并行执行,因此每一轮最多有|E|消息,每一层级的确认消息最多需要diamdiamdiam轮,因此每一层级的确认需要消息最多为diam⋅∣E∣diam\cdot|E|diamE,最多需要diamdiamdiam轮才能完成到rootrootroot的确认,因此通信复杂度为O(diam2⋅∣E∣)O(diam^2\cdot|E|)O(diam2E)
  • 算法应用

    • 广播:一条消息的广播可以建立在BFS tree上,利用SynchBFS构造的一颗每一个非叶子节点都包含其子节点的BFS树,因此广播一条消息只需从root一直向前传播,时间复杂度为O(diam)O(diam)O(diam),通信复杂度为O(n)O(n)O(n)
    • 全局计算:比如网络中所有节点求和,利用BFS tree从叶子节点开始,发送一个值给parent节点,非叶子节点等到汇集了所有子节点的输入,sum后发送给它的parent节点,直到root节点。如果在双向网络中,时间复杂度为O(diam)O(diam)O(diam),通信复杂度为O(n)O(n)O(n)
    • leader选举:所有节点初始并行发送消息进行选举,利用最大uid构造树,在双向网络中,时间复杂度为O(diam)O(diam)O(diam),通信复杂度为O(diam⋅∣E∣)O(diam\cdot|E|)O(diamE)
    • 计算图的直径(FloodMax需要用到):所有节点并行发送消息执行SynchBFS算法,每个进程利用max−distimax-dist_imaxdisti来构建树,得每个节点得到一个最大值,然后在第二轮中,整个网络利用SynchBFS求出最大值。如果是双向网络,时间复杂度O(n)O(n)O(n),通信复杂度O(diam⋅∣E∣)O(diam\cdot|E|)O(diamE)
最短路径

SynchBFS解决了未带权边的搜索,但是实际环境中,有很多场景并不是这样简单的,通常节点间通信都是有开销的,这个开销我们可以抽象为权重,比如通信的延迟,或者通信的带宽等,接下来将介绍带权网络的算法

BellmanFord算法
  • 前提假设

    1. 有向网络
    2. 有向边关联了一个权重
    3. 每个节点知道连接边的权重
    4. 每个节点知道网络的大小
  • 进程维护状态

    1. distdistdist:从i0i_0i0到该节点的最短距离,i0i_0i0初始化为0, 其他初始化为∞\infin
    2. parentparentparent:最短路径的父节点,初始化为undefineundefineundefine
    3. roundroundround:轮数,当roundroundround为n-1时结束
  • 算法描述

    • 消息生成算法

      if round <= n-1 then
      	send (dist, uid) to out-nbrs
      
    • 进程状态转换算法,每一轮收到消息M的(dist,uid)(dist,uid)(dist,uid),收到M集合U

       if round <= n-1 then 
      	min := min(U.dist)
      	if min+weight < dist then 
      		dist := min.dist+weight
      		parent := min.uid 
      	round := round+1;
      
  • 算法图解

    • 初始状态

      在这里插入图片描述

    • 第一轮,红色的线表示最短路径

      在这里插入图片描述

    • 第二轮

      在这里插入图片描述

    • 第三轮,可以看到节点1,最短路径已经有更小的值,其父节点也换成了2,直到n−1n-1n1也就是round=5时,算法结束

      在这里插入图片描述

  • 复杂度分析

    • 时间复杂度为n−1n-1n1
    • 通信复杂度(n−1)⋅∣E∣(n-1)\cdot|E|(n1)E
最小生成树
SynchGHS算法
  • 前提假设

    1. 带权无向图
    2. 节点有uiduiduid
    3. 图大小已知
  • 进程维护状态

    1. leader:记录component(一个子树结构)的leader的uiduiduid
    2. k:level,每个level至少有2k2^k2k个节点
  • MWOE(最小权重出边):指连接两个component的最小权重的边,一个简单的图说明,橙色和蓝色分别是两个不同的component,两条红色的边都是两个component的连接边,权重11的边就是要找的MWOE
    在这里插入图片描述

  • 算法原理

    • 初始时,所有单个节点是一个component,每个节点的leader即是自己,每个component找出最小权重的出边MWOE,当一个component有多个节点时,会采用广播让各个节点找到MWOE,然后发送测试消息,看另一端的节点是否属于同一component,然后汇集MWOE到leader,leader得到整个component的MWOE。比如1只有一个边12,而3和2正好有同一条最小边0,所有这些操作都是并行执行的。

      在这里插入图片描述

    • 合并,leader通知component的MWOE的节点进行连接操作,节点将边加入树并通知端点节点进行同样的操作,然后节点uid大的端点节点利用树广播leader信息,宣布自己是leader,当有多个component合并成一个时,因为多个节点会广播leader信息,因此最终,整个component都会得到最大uid的leader信息,新component拥有了新的标识.(这里我的理解是可以直接使用当前component的Leader,但是书中描述的是用MWOE的端点uid大的作为新的leader)

    在这里插入图片描述

    • 算法终止,当所有的节点都联成一个图后,leader通知各节点寻找MWOE时,将没有MWOE了,因此leader通知各节点算法结束

      在这里插入图片描述

  • 复杂度分析

    • 时间复杂度:因为每一级合并至少有两个component合并,因此最多需要log⁡(n)\log(n)log(n)级可以完成MST构建,每一级需要的时间为O(n)O(n)O(n),因此时间复杂度为O(n⋅log⁡(n))O(n\cdot\log(n))O(nlog(n))
    • 通信复杂度:每一级,leader需要发送消息通知树的各个节点寻找MWOE,图中共有n个节点,找到之后还要汇集结果,因此消息数为2⋅n2\cdot n2n,因此通信复杂度为O(n)O(n)O(n),各个节点探测MWOE时,可能每条边都要探测,因此还需要额外的∣E∣|E|E通信消息,因此整体的通信复杂度为O((n+∣E∣)log⁡(n))O((n + |E|)\log(n))O((n+E)log(n))
  • 优化:在测试边时,如果是一条内部边也就是端点都是同一component,那么就标记为"rejected",当探测时,如果一条边是rejected,那就不需要发送探测消息,因此探测通信总共只需要执行∣E∣|E|E次,因此通信复杂度为O(nlog⁡(n)+∣E∣)O(n\log(n) + |E|)O(nlog(n)+E)

最大独立集(MIS)
  • 定义:假设有无向图G=(V,E)G=(V,E)G=(V,E),其中I⊆VI \subseteq VIV是图的独立集,当且仅当i,j∈I(i,j)∉Ei,j \in I (i,j) \notin Ei,jI(i,j)/E,通俗的讲就是最大独立集中的任意两个节点之间没有边相连,因此MIS不是唯一的。III是最大独立集当任意I‘I^`I包含IIII‘I^`I不是独立集
  • 前提假设
    1. 知道图的大小nnn
    2. 不假设节点有uiduiduid
  • 算法核心思想:每次选择独立集I‘I^`I,然后将I‘I^`I执行操作I:=I⋃I‘I := I\bigcup I^`I:=II,然后从图GGG中删除I‘I^`I的邻居,直到GGG为空,因此问题的关键是求I‘I^`I
LubyMIS算法

利用随机化算法求I′I^{\prime}I

  • 算法思想:每个节点iii随机选择一个随机数valival_ivali(范围1≤vali≤4n1 \le val_i \le 4^n1vali4n),然后相邻节点之间发送消息valival_ivali的最大为winnerwinnerwinnerwinnerwinnerwinner会通知它的相邻节点为loserloserloserloserloserloser会被从图GGG中移除

  • 进程维护状态

    1. roundroundround:取值{1,2,3},初始值1
    2. valvalval:取值{1≤val≤4n}\{1 \le val \le 4^n\}{1val4n},初始任意值
    3. awakeawakeawake:boolean值,初始值true
    4. rem−nbrsrem-nbrsremnbrs:剩余没有选择的邻接节点,初始化为图的所有邻接节点
    5. statusstatusstatus{unknown,winner,loser}\{unknown, winner, loser\}{unknown,winner,loser},初始值unknownunknownunknown
  • 算法描述

    • 随机数生成

       if awake and round = 1 then val := random
      
    • 消息生成算法

      if awake then
      case
      	round = 1:
      		send val to all nodes in rem-nbrs
      	round = 2:
      		if status = winner then
      			send winner to all nodes in rem-nbrs
      	round = 3:
      		if status = loser then
      			send winner to all nodes in rem-nbrs
      endcase
      
    • 状态转换算法

      if awake then
      case
      	round = 1:
      		if val > v in all incoming values v then status := winner
      	round = 2:
      		if a winner message arrives then status := loser
      	round = 3:
      		if status in {winner,loser} then awake:=false
      			rem-nbrs := rem-nbrs - {j: a loser message from j}
      endcase
      round := (round+1) mod 3
      
  • 算法图解

    • 初始状态,注意LubyMIS算法并不需要uiduiduid,图中的字母编号仅仅是为了方便图的说明,不是uiduiduid,初始时所有节点awakeawakeawake都是true,状态都是unknownunknownunknownvalvalval任意值,统一初始化为0

    在这里插入图片描述

    • 第一阶段结果示意图,每个阶段有三轮,这里只展示结果,橙色节点代表winnerwinnerwinner节点,蓝色节点代表loserloserloser节点,注意观察,不管蓝色节点还是橙色节点awakeawakeawake都是false,也就是它们已经结束不会再参与算法运行,可以看到已经只有a、k节点会进入下一阶段

      在这里插入图片描述

    • 第二阶段结果示意图,经过第二轮,重新生成随机数,所有节点awakeawakeawake都是false,全部节点都已经运行结束,因此该图的最大独立集为(a,c,e,h,k)(a,c,e,h,k)(a,c,e,h,k)

      在这里插入图片描述

  • 随机化算法作用:主要作用是打破对称性,是一个非常常用的小技巧,比如在解决活锁,在raft协议选举失败时为了避免所有节点同时发起选举,失败后都会随机等待一段时间后发起选举

总结

本文主要讲了分布式同步网络中的BFS、最短路径、MST问题,接下来的文章将简单介绍分布式同步网络另一个关键性问题,一致性问题

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值