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

引言

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

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

广度优先搜索

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

SynchBFS算法
  • 前提假设

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

    1. p a r e n t parent parent:记录进程的父节点是谁
    2. m a r k e d marked marked:记录是否被标记
  • 算法流程

    • 选择一个节点作为初始节点,定为 i 0 i_0 i0,设置为已标记, i 0 i_0 i0发送一条search消息到节点 i i i o u t − n b r s out-nbrs outnbrs
    • 对于任意一个节点,如果节点还未被标记,并且收到search消息,则它将自己标记,并且将发送search消息的节点设置为它的parent,然后发送search消息到它的 o u t − n b r s out-nbrs outnbrs
  • 算法图解

    • 初始化选择4(可以随意选择)为root节点 i 0 i_0 i0

      在这里插入图片描述

    • 第一轮search消息,4只有一个 o u t − n b r s out-nbrs outnbrs,所以只有一条消息,5被标记,其parent节点为4,红色箭头代表search消息

      在这里插入图片描述

    • 第二轮search消息,5有两个 o u t − n b r s out-nbrs outnbrs

      在这里插入图片描述

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

      在这里插入图片描述

  • 复杂度分析

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

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

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

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

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

BellmanFord算法
  • 前提假设

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

    1. d i s t dist dist:从 i 0 i_0 i0到该节点的最短距离, i 0 i_0 i0初始化为0, 其他初始化为 ∞ \infin
    2. p a r e n t parent parent:最短路径的父节点,初始化为 u n d e f i n e undefine undefine
    3. r o u n d round round:轮数,当 r o u n d round round为n-1时结束
  • 算法描述

    • 消息生成算法

      if round <= n-1 then
      	send (dist, uid) to out-nbrs
      
    • 进程状态转换算法,每一轮收到消息M的 ( d i s t , u i d ) (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 − 1 n-1 n1也就是round=5时,算法结束

      在这里插入图片描述

  • 复杂度分析

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

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

    1. leader:记录component(一个子树结构)的leader的 u i d uid uid
    2. k:level,每个level至少有 2 k 2^k 2k个节点
  • 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 ⋅ n 2\cdot n 2n,因此通信复杂度为 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 ( n log ⁡ ( n ) + ∣ E ∣ ) O(n\log(n) + |E|) O(nlog(n)+E)

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

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

  • 算法思想:每个节点 i i i随机选择一个随机数 v a l i val_i vali(范围 1 ≤ v a l i ≤ 4 n 1 \le val_i \le 4^n 1vali4n),然后相邻节点之间发送消息 v a l i val_i vali的最大为 w i n n e r winner winner w i n n e r winner winner会通知它的相邻节点为 l o s e r loser loser l o s e r loser loser会被从图 G G G中移除

  • 进程维护状态

    1. r o u n d round round:取值{1,2,3},初始值1
    2. v a l val val:取值 { 1 ≤ v a l ≤ 4 n } \{1 \le val \le 4^n\} {1val4n},初始任意值
    3. a w a k e awake awake:boolean值,初始值true
    4. r e m − n b r s rem-nbrs remnbrs:剩余没有选择的邻接节点,初始化为图的所有邻接节点
    5. s t a t u s status status { u n k n o w n , w i n n e r , l o s e r } \{unknown, winner, loser\} {unknown,winner,loser},初始值 u n k n o w n unknown unknown
  • 算法描述

    • 随机数生成

       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算法并不需要 u i d uid uid,图中的字母编号仅仅是为了方便图的说明,不是 u i d uid uid,初始时所有节点 a w a k e awake awake都是true,状态都是 u n k n o w n unknown unknown v a l val val任意值,统一初始化为0

    在这里插入图片描述

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

      在这里插入图片描述

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

      在这里插入图片描述

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

总结

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值