知识点整理(六)——图解Raft协议

什么是分布式共识?

假设我们有一个单节点系统,这个系统用于存储一个值。

我们还有一个可以向服务器发送值的客户端。

图中左侧绿色的圆代表客户端,右侧蓝色的圆代表单节点存储系统,用于存储一个值x。

客户端发送一个数值(8)给服务端,服务端存储这个值。

只有一个节点的系统,很容易达成系统共识。但如果我们有多个节点,我们如何达成共识呢?

这就是分布式共识问题。

Raft是一种实现分布式共识的协议。

Raft是如何工作的?

一个阶段有3种不同的状态:Follower(追随者)Candidate(候选人)Leader(领导者)。

一开始所有节点都是Follower。

如果Follower没有得到Leader的心跳,那么他们可以成为Candidate。

图中节点a变成Candidate。

Candidate给其他节点发送请求投票,其他节点将投票回应。

Candidate得到了大多数节点的投票,就会变成Leader。这个过程被称为领导者选举。

现在系统的所有更改都必须经过Leader。

每一个更改都会被记录一条节点日志,这个修改暂时不会被提交,值不会被系统设置。要提交这个修改,需要节点把日志发给所有Follower。然后Leader等待大多数节点都写好了日志,然后修改再leader上进行提交,系统将值设置为新值(5),最后Leader通知所有Follower已提交的事件。

现在集群就达成了共识。这个过程称为日志复制。

领导者选举

在Raft中有两个控制选举的超时设置。

第一个是选举超时,选举超时是Follower等待成为Candidate的时间,这个时间随机设置在150ms到300ms之间。

在选举超时后,Follower成为Candidate,并开始一个新的选举任期,开始为自己投票,并发投票举请求给其他节点。

如果接收请求的节点在这一选举任期中还没有投票,那么它将投票给这个Follower,并重置自己的选举超时时间。

Leader在选举超时间隔内发送指定心跳信息给Follower,Follower重置自己的选举超时时间。

这个选举任期将持续到一个Follower心跳超时并成为Candidate为止。

现在C节点成为了Leader。

分票的情况

当每个Candidate都只获得半数以下的票时,节点会等待新的选举,再试一次。由于等待时间是随机的,所以几乎很难出现再次分票的情况。

分区

集群系统不可避免出现分区,Raft是如何解决分区的情况呢?

刚出现分区时,每个区域会各自选举Leader。由于分区会产出2个不同的Leader。

给2个分区设置不同的值,节点数在一半以下的分区无法提交日志,因为没有获得半数以上节点的日志写入。而节点数在半数以上的分区Leader可以提交日志。

当分区消失时,节点B会察觉未获得半数以上节点投票,此时被迫放弃Leader。A B节点会回滚未提交日志,并从Leader(C)节点同步日志。最后整个系统达成共识。