• 分布式一致性算法 -- Raft


          Raft 应该是目前使用最广泛的分布式一致性算法,像目前很受欢迎的 Kubenetes 中的分布式一致性键值存储系统 etcd 就是采用的 Raft 算法。
          与 Paxos 相比较, Raft 更简洁,Paxos 为了保证每个节点数据的一致性,每一次操作都需要进行至少两轮的消息交换(可以查看上一篇关于 Paxos 算法的总结)。而 Raft 不同 ,在 Raft 算法的体系中正常情况下只存在一个 Leader 节点,Leader 处理来自客户端的所有变更请求,选举 Leader 的过程可能至少需要一轮,但是在选取了 Leader 之后,每次处理来自客户端的请求就只需要一轮消息更换(下面会解释)。
          关于 Raft 实现过程可以参考以下网址,动画效果更有利于理解:

          ##### Raft动画展示 ****************

    三种状态

    • Leader 领导者状态
      所有的变更操作都由领导者节点去处理
    • Candidater 候选者状态
      可以竞争成为领导者
    • follower 追随者状态
      接受领导者发送的变更日志,同时也可以成为候选者

    选举

    选举超时

    每一个追随者节点都有一颗做领导者的心,他们会随机一个时间段去考虑要不要竞争成为领导者,如果在此期间接收到领导者或候选者发来的消息,就会打断当前考虑过程,重新考虑,选举超时控制在 150ms300ms 之间。

    选举机制

    Raft 通过心跳机制来触发领导者选取,当追随者接收到来自领导者或者候选者的有效 RPC 时,就会保持自己追随者的身份。而当在选举超时时间内没有接收到心跳消息的时候,就认为当前集群中没有领导者,自身会进入候选状态,开始新的一轮选举任期。

    选举过程

    1. 选举超时后,追随者会成为候选人并开始新的选举任期,节点会先为自己投票,然后给其他节点发送投票请求。
    2. 如果接收节点在这个任期内还没有投票,并且候选人的日志比自己新,那么它会投票给候选人,并且接收节点重置其选举超时(为了最大限度确保只能有一个领导者,当接收到有候选人时,自身就不考虑竞争成为领导者)。
    3. 一旦候选人获得多数票,它就会成为领导者,领导者开始向其追随者发送附加条目消息,这些消息以心跳超时指定的间隔发送。
    4. 追随者响应每个附加条目消息,这个选举期限将持续到一个追随者停止接收心跳并成为候选人。
    5. 当发生脑裂(即有两个节点同时竞选领导者并各自获取到了一半的票数)情况时,会触发一次新的选举任期。

    在选举过程中,候选者会一直处于候选状态,直到出现以下情形之一:

    • 当前候选者赢得了选举称为领导者,开始给所有追随者发送心跳消息
    • 其他的服务器成为了领导者,并接收到来自领导者的心跳消息,自身候选状态解除
    • 在一段时间之内没有服务器赢得选举,例如脑裂情况,此时候选者会再次发起选举

    日志复制

    过程

    1. leader 收到来自客户端的变更请求,如将值 A 修改为 6
    2. leaderA -> 6 的变更信息保存在日志中,但是该条信息并未提交,因此并不是真正的修改成功,不会修改节点上的值。
    3. leader 在下一次心跳连接时,将 A -> 6 的日志信息一并发送给所有的 follower 节点。
    4. follower 节点受到来自 leader 的变更信息,将 A -> 6 信息写入日志中,并回复 leader ,如果 leader 接收到了大多数 follower 节点的回复信息,那么就认为当前变更信息可以生效,会提交当前条目,并修改当前节点状态机上的值。
    5. 随后 leader 通知 follower 该条目已经提交,follower 接收到提交通知后修改自身节点状态机上对应的值。
    6. leader 回复客户端执行结果

    提交的作用

    提交最终表示集群中大多数的服务器完成了客户端请求的日志写入,它保证了以下两点:

    1. 容错:
      在集群服务器部分故障,但仍有多数服务器可以正常工作的情况下,集群仍能正常处理来自客户端的请求
    2. 确保重叠:
      即便集群中由少部分的服务器响应失败,总有一个服务器能包含之前提交的所有条目。

    保证领导者保存了所有的日志条目

    在上面的选举过程中和日志复制过程中,我们可以看到,只要集群中大多数服务器相应成功即可完成操作,所以,集群每个服务器中的日志并不一定完全一样。当在一个新的选举任期过程中,我们必须保证领导者中的日志保存了所有的提交的日志条目,否则之前已经提交过的日志就有可能被覆盖掉。
    所以需要以下两点保证领导者的权威性:

    1. 日志条目只有复制到多个服务器上时(收到多个服务器的日志写入成功消息),才能提交。如果当前日志条目被提交,那么之前的日志条目也都被间接的提交了。
    2. 候选者只有赢得了多个服务器的投票时,才能成为领导者。其他服务器投票时会判断候选者的日志是否比自己的新,比自己的新才会投票。
  • 相关阅读:
    弹窗示例(小白示例)
    在 Spring Boot 中使用 JDBI
    ios UI 基础开发一
    SpringCloud无介绍快使用,Nacos集群和Nginx代理(二十)
    LeetCode【42】接雨水
    Python 基础合集4:Python的数据结构(str、list、tuple、dict、set)
    C++面试八股(一)
    【Linux服务器架设】存储服务器构建原理-NFS
    [C++]ifstream和getline获取中文乱码解决方案
    2022双十一激光投影仪哪个好?当贝激光投影系列 高品质大品牌更有保障
  • 原文地址:https://blog.csdn.net/qq_40096897/article/details/126208772