分布式选举算法笔记

定义问题

分布式选举算法笔记_第1张图片
image.png

System Model

分布式选举算法笔记_第2张图片
image.png

算法

1. Bully Algorithm

简单来说就是基于Membership list,id最大的当leader。选举过程会有各种发消息的逻辑,懒得去记,可以理解为本质上是基于All-to-All heartbeating timeout的failure detect(如图1)。
这么一想的话,zookeeper/etcd做选举(即基于membership List选最大id的节点当主节点)其实也是Bully Algorithm,只不过fail detect是通过centralized heartbeating(如图2,出自C3)做的,避免了脑裂问题。

分布式选举算法笔记_第3张图片
图1.All-to-All heartbeating

分布式选举算法笔记_第4张图片
图2.centralized heartbeating

缺点:

  1. 新节点加入/恢复时,会有频繁切主的问题
  2. 选举过程中如果不断有fail或者timeout,在异步模型中liveness没法保证。
    3.个人理解,选举过程中如果不断有fail或者timeout,有节点不断fail、fail recover、fail,看起来连同步模型都没法保证liveness。
    4.个人理解,通过All-to-All heartbeating做fail detect然后选主是有脑裂问题的。

注:看极客时间讲MongoDB是基于Bully的,觉得很不可思议,翻了下官网说是MongoDB也基于共识算法做选举。

2. Ring-based

节点在环上击鼓传花式的通信。没见过哪个系统用,遇到再复习吧

3. 基于共识算法

可以通过共识算法选主,如图3。能保证safety,但是(当不断有故障/高延迟timeout发生)依然不能保证liveness。


分布式选举算法笔记_第5张图片
图3.通过共识算法选主

具体在实现时有很多可以优化的细节:

  • chubby的方案用到Master lease,避免新节点频繁切主。没细看是怎么实现的。

  • zookeeper是每个节点生成一个比zk file system里存的id更高的id,然后写入fs,id最高的成为主节点;为避免id冲突,加入了一个quorum 2pc。值得一提的是,为避免惊群效应,用的是Ring-based failure detect,如图4所示。

    分布式选举算法笔记_第6张图片
    图4.zk中的fd

    zk怎么解频繁切主问题?按这里的讲法,每个节点的数据id是用的本地存储的最大id,新加入节点没数据、数据id不会是最大,因此不会成为主节点、不会切主。

  • etcd用Raft选主的细节没看。

工程实践中

实践中我们做选举功能往往是基于zk/etcd这类中心化的线性化存储。此时System Model就变了,变成:

  • N个processes和一个线性化存储
  • 每个process有一个唯一id
  • 假设线性化存储不会fail(线性化存储自己通过fo实现高可用,对外透明);如果线性化存储fail,那么系统无法选举,即选举算法并不对线性化存储容错

在这种System model下,选举算法的实现和抢锁的实现一样,有:

  1. 基于原子cas+Watch。
    本质上是一种centralized failure detect,有惊群问题
  2. Ring-based failure detect
    每个节点存储不同的id,所有id就是一个membership list。id最大的作为主节点,每个节点Watch比自己大的节点。

你可能感兴趣的:(分布式选举算法笔记)