图解RAFT成员变更

图解RAFT成员变更

    • 问题是怎样的?
    • 一个一个节点扩充
    • Joint Consensus 过渡态

这几天看了不上网上关于RAFT的成员变更的介绍,基本上是对原论文的翻译,毫无解释可言。因此准备结合自己的理解,通俗易懂地介绍一下成员变更的过程。这里面主要有2种方法,是本人搜集了一些论文总结思考所得。

问题是怎样的?

想象在我们的共识算法中,现在有3个节点,我们若想增加至5个节点,一般如何处理?

常用的方法是让所有服务器停机,再进行更新。那为什么要这么做呢?

这里引用论文中的图片。如图,我们在原有集群中有Server1, Server2, Server3三个服务器。现在想加入Server4和Server5。若Server3首先进行了更新,这个时候就出现了问题。

在Cnew新的配置中,5个服务器的大多数为3,在Cold旧的配置文件中,3个服务器的大多数为2。而现在就可能出现有2个Leader的情况。Server1请求Server2给自己投票,便获得了大多数投票。Server4请求Server3和Server5投票,也获得了自己配置文件中的大多数投票。(这里省略了自己给自己投票的描述)。
图解RAFT成员变更_第1张图片
在同一个集群中,我们处理客户的请求,需要保持最终结果一致性。若出现2个Leader,究竟听谁的命令呢?因此这将无法维持结果一致性。

所以,目前大多数企业的操作方式是让服务停止,然后对其进行更新,待更新完毕后,重新启动集群。

一个一个节点扩充

因此有人提出了以下这个方案,我们一个一个来。那接下来看看能不能解决问题。

如图,节点D加入集群,告知Leader,Leader随后对本地进行更新,并通知其他节点。
图解RAFT成员变更_第2张图片

这里主要分析极端情况,如图,若A首先更新,之后A掉线,会不会出现2个Leader?
①对于D而言,他若想成为Leader需要集群中的3个节点同意才可以完成竞选,而B,C在旧的配置中无法察觉D的存在,也不会给他投票。

②对于A,他本身就是Leader,若他竞选,需要得到B,C其中一位投票才能继续成为Leader。此外,竞选成功后,他会继续执行B,C的扩充指令,直至完成更新。

③对于B,C他们可以互相投票,成为Leader,但若投票之后,A无法成为Leader,因此不会出现2个Leader同时出现的情况。

图解RAFT成员变更_第3张图片

Joint Consensus 过渡态

该方法主要针对一次扩充多个节点,以及替换节点的情况。这里主要分析,一次扩充多个节点。

如图,ABC为旧的集群中的节点,D,E为新集群中的节点。
图解RAFT成员变更_第4张图片

现在,C节点进行了中间态,原文称为(Cold_new)。在该状态,若想成为Leader需要新旧集群中的大多数节点都给他投票才行。即(A,B,C)U (A,B, C, D, E)中大多数,这两个条件都需要满足。

我们分析下图的情况:
①A,B可以互相投票称为Leader。

②C需要获得A,B中的一票,且获得A,B,D,E中的两票才能称为Leader。因此②与①互斥。

③D,E若想成为Leader需要A,B,C,D,E中的大多数给他投票,但A,B作为旧集群的节点,并不会给新集群的节点投票。

但不妨假设可以给他们投票,D,E需要A,B,C中的一票:

  1. 若为A投票,则A,B不会成为Leader;同时,C由于没有获得A,D,E三个人的其中一票,也无法成为Leader。
  2. 若C给他们投票,A,B中也选出一个Leader,那就出现了2个Leader。

因此这里需要禁止C给新集群中的节点投票。这个是我自己想的,原文并没有明说。
图解RAFT成员变更_第5张图片
当旧集群中大多数节点更新之后,原论文称此时只有过渡态的节点可以被选为Leader。因此这里我们又可以推出过渡态无法给旧节点投票。不过个人认为即使可以给旧节点投票,也不会造成分歧,具体分析和上一种情形类似。
A成为Leader后也可以继续给集群服务,并进行自我更新。

②同样,D,E同样无法得到A,B,C的投票。

③因此只有B,C可以获得大多数节点投票成为Leader。

图解RAFT成员变更_第6张图片

当大多数节点成为过渡态后,可以向新的配置文件更新。如图,此时B已经更新为新的配置文件。

①此时B,D,E可以竞选成功(接受同为新集群的节点投票),成为Leader。

②C也可以竞选成功,但需获得(B,D,E中的一位),因此与①互斥。

③A则无法竞选成功。

图解RAFT成员变更_第7张图片
当大多数节点都更新为Cnew后,系统则可以按照新的配置文件继续运行。

你可能感兴趣的:(区块链,共识算法)