raft协议原理

Raft 是一个基于 Raft 协议的分布式一致性算法,它实现了一种双向的协作式的领导者选举和成员投票的过程,从而保证了分布式系统的高可用和一致性。Raft 协议在 Data Center 领域有很多的应用,比如 Microsoft 的 Azure 和 AWS,以及 Google 的 Kubernetes。

Raft 协议的核心思想是领导者选举和成员投票。具体来说,系统中的每个节点都会被选举为新的领导者,称为 alpha 节点。alpha 节点会向其所有的 follower 节点广播其选举结果,并开始执行其领导者的职责。同时,alpha 节点还会监听 follower 节点的心跳请求,以确保选举过程的正常进行。当 alpha 节点故障、死亡或者被其 follower 节点选举为新的领导者时,会自动退出领导者职责,并将领导者职责移交给其 follower 节点。

Raft 协议还提供了一种数据一致性的保证机制。具体来说,每个 follower 节点都会在其日志中记录其领导者选举和任期的结果,以确保系统中所有节点都具有相同的历史记录。这种数据一致性保证了在系统出现故障或者节点失效时,仍然可以通过领导者选举和成员投票的过程实现系统的高可用和一致性。

总之,Raft 协议是一种基于领导者选举和成员投票的分布式一致性算法,它能够保证分布式系统的高可用和一致性。在 Data Center 领域,Raft 协议已经被广泛应用,并且在 Microsoft 的 Azure 和 AWS,以及 Google 的 Kubernetes 中都得到了成功的部署和验证。

Raft 协议中的投票和领导选举过程如下:

  1. 初始状态:每个节点初始化后的心跳超时时间都是随机的,任期编号都为 0,角色都是跟随者。
  2. 请求投票:节点等待心跳超时后,会向其所有的 follower 节点发起请求投票信息,此时任期编号 +1,自荐会获得自己的一票选票。
  3. 跟随者投票:跟随者收到请求投票信息后,如果该候选人符合投票要求后,则将自己宝贵的一票投给该候选人,同时更新任期编号。
  4. 当选领导者:当节点 C 赢得大多数选票后,它会成为本次任期的领导者。
  5. 领导者与跟随者保持心跳:领导者周期性发送心跳消息给其他节点,告知自己是领导者,同时刷新跟随者的超时时间,防止跟随者发起新的领导者选举。

以上是 Raft 协议中投票和领导选举过程的简要概述。在实际应用中,还需要根据具体情况对协议进行修改和优化,以满足不同的应用场景和需求。

选举分几种场景:

  • 1.新节点加入

    当有一个节点加入当前的分布式集群的时候,leader会检测并发现它并给他发送消息。使其加入此分布式集群。

在这里插入图片描述

  • 2.leader掉线处理

    假设我们现在的服务器A掉线,由于没有leader维持心跳消息,这个时候服务器B和C会进入超时倒计时的状态。 在这里插入图片描述
    • 200ms过去,服务器B开始超时了,这个时候它揭竿而起成为candidate,并向节点C发送消息请求其支持自己成为leader。

在这里插入图片描述  

之后,在一系列判断条件之后(后面会讲),节点C会回复节点B的请求信息。插句题外话哈,在B还没收到C的回复消息之前,假设A只是刚刚网络不通畅,现在死而复生,给B发送消息了。那么B发现A的时期比自己落后了,这还等什么?!苍天已死,黄天当立,之后反手将其收为小弟。

在这里插入图片描述

之后节点b顺利成为leader。

在这里插入图片描述

3.多个 follower 同时掉线

现在假设有4个节点:A、B、C、D。其中A和D的超时时间是相同的。

在这里插入图片描述
150ms过后,A和D同时成为candidate,争相为了成为leader给B和C发消息。 在这里插入图片描述


这个时候有对于B和C有两个选择,一个是它们一起支持两个中的一次,也就是要么支持A要么支持D,这样这样其中一个就会成为leader,我们假设它们两个都支持A。

在这里插入图片描述

另外一种选择就是,A和D各的一票支持,它们的支持者跟进它们各自的leader的时期,然后本轮选举结束。

在这里插入图片描述
之后50ms过去之后,B的超时时间过期了,其获得candiate的资格,这个时候其会向其他follower发送消息请求支持。

 在这里插入图片描述


之后A、B、D 因为当前的B也没有支持者,所以就会支持B,B顺利成为leader。

在这里插入图片描述
日志复制

当我们的集群leader 选举之后。Leader 接收所有客户端请求,然后转化为 log 复制命令,发送通知其他节点完成日志复制请求。每个日志复制请求包括状态机命令 & 任期号,同时还有前一个日志的任期号和日志索引。状态机命令表示客户端请求的数据操作指令,任期号表示 leader 的当前任期,任期也就是上图中的时期。

而当follower 收到日志复制命令会执行处理流程:

follower 会使用前一个日志的任期号和日志索引来对比自己的数据:

如果相同,接收复制请求,回复 ok;
否则回拒绝复制当前日志,回复 error;
leader 收到拒绝复制的回复后,继续发送节点日志复制请求,不过这次会带上更前面的一个日志任期号和索引;

如此循环往复,直到找到一个共同的任期号&日志索引。此时 follower 从这个索引值开始复制,最终和 leader 节点日志保持一致;

在这里插入图片描述
日志复制过程中,Leader 会无限重试直到成功。如果超过半数的节点复制日志成功,就可以任务当前数据请求达成了共识,即日志可以 commite 提交了;

注:
这里要提到的一点就是,如果follower发现canidate的日志还没有自己的新(索引号没自己大),其是不会支持其成为leader的。
 

你可能感兴趣的:(java,raft,一致性协议)