当前位置: 首页 > article >正文

Raft 常见问题解答

1. 在Raft协议中,什么是Leader选举?Leader选举失败怎么办?

在Raft协议中,Leader选举是一个关键过程,用于选出一个节点来管理日志条目的复制和维护集群的一致性。整个选举过程如下:

  1. 开始选举:当一个节点(称为候选者candidate)没有在一定时间内接收到当前Leader的心跳信息时,它会认为Leader已经失效。这时,候选者会增加自己的任期号(term),并启动一次Leader选举。

  2. 请求投票:候选者向集群中的其他节点(称为追随者followers)发送请求投票的消息。在这个消息中,候选者会包含自己的任期号和日志信息。追随者会根据自己的日志和任期号判断是否投票给该候选者。如果追随者的日志不比候选者的旧,并且追随者还没有在当前任期内投票给其他节点,则它会投票给这个候选者。

  3. 计票和结果:如果候选者从集群的大多数节点获得了投票,那么它就被选为新的Leader。新Leader随后会向所有节点发送心跳消息(append entries),来维护其Leader地位,并开始处理客户端请求。

如果Leader选举失败,即候选者没有得到大多数的支持,可能的原因包括网络分区、票数分散等,选举过程将会重新开始。每个节点都可能再次成为候选者,发起新一轮的选举,直到某个节点获得大多数票数。在实践中,通常通过增加选举超时时间的随机性来减少选举冲突和提高选举成功的机会。

2. Candidate只能有一个吗?

不是的,可以有多个,尽管Raft算法要求每个节点有一个随机的选举超时,以减少多个节点同时成为候选人的概率,但这种情况仍然可能发生。如果两个或更多的follower几乎在同一时间触发了它们的选举超时,它们都会转变为候选人状态。

那么,当多个节点同时变成候选人时,它们各自增加它们的任期号,并向其他节点发送请求投票的消息。虽然可能有多个候选人,但只有一个候选人能在那个任期内获得大多数的投票。

选举结果

    1. 一个候选人获胜:如果某个候选人获得了大多数票,他将成为新的领导者。
    2. 选举分裂:如果没有任何候选人能在这一任期内获得大多数票(例如,票数平分),则这一任期的选举会失败。在这种情况下,各个候选人将重新开始选举,包括再次随机设置选举超时并增加任期号

3.Candidate 可以投票吗?还是只有 follower 可以投票

在Raft算法中,当一个节点成为candidate(候选人)时,它首先会给自己投票,然后向其他节点发送请求投票的消息。每一个节点只有一票,因此一旦节点成为candidate并给自己投了票,它就不会在该任期内投票给其他candidate了。这个机制是为了保证选举的效率和公平,避免无休止的选举循环和选票分散。

4. Raft协议中有哪些角色?分别负责什么任务?且他们的转台是如何转化的。

有leader,fellower,candidate。转换流程参考图,文来自小徐先生的编程世界

raft 算法中,集群节点的角色类型分为:领导者 leader、跟随者 follower、候选人 candidate 三种角色 . 各角色的具体职
(1)leader -> follower
倘若 leader 发现当前系统中出现了更大的任期,则会进行“禅让”,主动退位成 follower.
这里 leader 发现更大任期的方式包括:

I 向 follower 提交日志同步请求时 , 从 follower 的响应参数中获得 ;

II 收到了来自新任 leader 的心跳或者同步日志请求;III 收到了任期更大的 candidate 的拉票请求 .
(2)follower -> candidate
leader 需要定期向 follower 发送心跳,告知自己仍健在的消息 .
倘若 follower 超过一定时长没收到 leader 心跳时,会将状态切换为 candidate ,在当前任期的基础上加 1 作为竞选任
期,发起竞选尝试补位 .
(3)candidate -> follower
candidate 参与竞选过程中,出现以下两种情形时会退回 follower:
I 多数派投了反对票;
II 竞选期间,收到了任期大于等于自身竞选任期的 leader 传来的请求 .
(4)candidate -> leader
candidate 竞选时,倘若多数派投了赞同票,则切换为 leader.
(5)candidate -> candidate
candidate 的竞选流程有一个时间阈值 . 倘若超时仍未形成有效结论(多数派赞同或拒绝),则会维持 candidate 身份,
将竞选任期加 1,发起新一轮竞选 .

5. Raft协议中的Term是什么?如何使用Term来保证一致性?

每一次任期从一次选举开始,唯一的 term 和日志号可以确定唯一的日志。当发起新的Leader选举时,candidate会增加自己的Term编号,并向其他节点发送包含新Term的投票请求。其他节点检查Term,只有当请求的Term不小于自己当前的Term时,它们才会考虑投票。每个日志条目都被标记上它被创建时的Term编号。这有助于节点在复制过程中解决日志不一致的问题。

6. 在Raft协议中,如何避免过多的Leader选举导致性能下降?

选举超时时间随机化:在Raft中,每个节点的选举超时时间是随机的,这意味着不是所有的节点都会在同一时间触发选举。这样可以防止多个节点同时成为candidate并发起选举,从而减少选举冲突和提高选举的效率。

7. Raft协议中的心跳机制是什么?它有什么作用?

心跳是由领导者定期发送给所有跟随者的一种轻量级通信信号。

  1. 维持权威性:心跳信号表明领导者仍然处于活跃状态,帮助维持其对集群的领导权威。防止跟随者的选举超时发生,从而避免发起不必要的领导者选举
  2. 一致性维护:虽然心跳本身不包含日志条目,但它确保了领导者与跟随者之间的通信,有助于维持系统的一致性状态

8. Raft协议中的Quorum是什么?它有什么作用?

Quorum(法定人数),用于决定集群中的多数节点。具体来说,Quorum是指活跃的集群节点中必须达到的最小数量,这个数量必须是集群总数的半数以上一点(即大多数),这样的设计可以保证数据的一致性和系统的高可用性。


9. 日志复制的机制 

客户端向集群的Leader发送写命令,Leader首先将这些命令作为新的日志条目加入到自己的日志中。Leader在随后的AppendEntries RPC中包含最新的提交信息,Followers据此更新自己的提交索引。一旦日志条目被提交,Leader和Followers会将这些日志条目应用到它们的状态机中。这确保了所有节点都能以相同的顺序执行相同的命令,从而保持状态一致。如果在复制过程中发现Follower的日志与Leader不一致(如缺少条目、条目冲突等),Leader会根据Follower的回复调整发送的AppendEntries RPC,包括减少发送的条目的数量或者更早地开始发送,以解决不一致。如果 fellower 没有更早的条目,leader 就一次次发送更早的条目。

值得注意的是,在每次新 leader 当选后都会有一个 no - op 阶段,

原因见下文,来自小徐先生的编程世界


10. Raft协议中的日志压缩(log compaction)是什么?有什么作用?


为什么要有 log compaction?

日志压缩(log compaction)是一种优化机制,用来处理随着时间推移日志不断增长的问题。在没有日志压缩的情况下,日志条目会无限增加,这将消耗大量存储空间。

日志压缩的实现

Raft协议通过引入“快照”(snapshot)来实现日志压缩:

  • 快照创建:定期地,或当日志达到一定大小时,系统会将当前状态机的状态(即由日志条目序列化执行得到的结果)生成快照。
  • 存储状态:这个快照会包含达到该状态所需的所有信息,并与一个特定的日志索引及任期号相关联,这个索引和任期号指示快照包含的最后一个日志条目。
  • 日志截断:创建快照后,Leader和Follower可以删除那些已经被快照覆盖的旧日志条目,从而释放存储空间。

日志压缩的作用

  • 节省存储空间:通过定期删除旧的日志条目,减少存储需求。
  • 加快恢复速度:新节点加入集群或现有节点需要从故障中恢复时,可以直接加载快照并应用之后的日志条目,而不是从头重放所有日志,这大大减少了恢复时间。
  • 提高性能:减少了日志条目数量,可以加快日志复制和索引的查找速度。

处理快照的方式

  • 快照传输:当Follower落后太多,无法通过正常的日志条目复制来同步时,Leader可以发送快照给Follower。
  • 快照安装:Follower收到快照后,会将其加载到自己的状态机中,更新自己的日志索引和任期信息,然后继续应用新的日志条目。

只要最后的结果吗?

通常情况下,Raft确保所有参与的节点最终都具有完全一致的状态。对于大多数应用场景,节点不需要关心到达最终状态的每一个中间状态,只需要确保最终状态是准确和一致的。这意味着只要最后的结果通常就足够了。

(来自https://juejin.cn/post/7342718848816201740)

11. Raft协议如何防止脑裂(split brain)的问题?Raft协议如何处理节点宕机的情况?如何保证数据一致性不受影响?如何处理新增删除节点?

比较复杂,见下文,主要说的是要以老配置的节点来进行多数派的投票成果原则,来自小徐先生的编程世界


12. Raft协议有哪些局限性?有哪些场景下不适合使用Raft协议?它与其他分布式一致性协议相比有哪些优劣之处?Raft协议有哪些变体?

Raft的局限性

  1. 性能开销:Raft中的所有写操作都需要通过Leader,并且要求大多数节点的确认,这在高延迟或低带宽的网络环境下可能导致性能瓶颈。
  2. Leader依赖:系统的整体性能很大程度上依赖于Leader的性能。如果Leader节点发生故障,整个系统必须等待新的Leader选举和日志同步完成才能继续操作。
  3. 存储开销:虽然通过日志压缩可以部分解决,但长时间运行的集群仍可能因为日志条目过多而面临存储压力。

不适合使用Raft的场景

  1. 读多写少的场景:如果系统的读操作远远多于写操作,使用Raft可能不是最优选择,因为Raft优化了写操作的一致性和可靠性。
  2. 大规模节点:在节点非常多的环境中,维持大多数节点的同步可能会变得不切实际,尤其是在网络条件复杂或节点经常变化的情况下。
  3. 高可扩展性需求:Raft更适合中小规模的集群。对于需要非常高可扩展性和动态变化的系统,如全球分布式数据库,可能需要更复杂的协议。

与其他协议的比较

与Paxos相比:

  • 易于理解和实现:Raft被设计为比Paxos更易于理解和实现,尤其是在教育和实际应用中。
  • 结构化决策过程:Raft有明确的角色和规定的流程,如Leader选举和日志复制,而Paxos的多变体和配置可能更难以把握。
  • 性能相近:在正常运行条件下,Raft和Paxos在性能上相差不大,但在网络分区和节点故障的恢复方面,Raft可能更加直观和迅速。

Raft的变体

  1. Multi-Raft:用于支持多个Raft群组共存,可以在不同的群组间分配不同的数据集,提高了扩展性和隔离性。
  2. Hierarchical Raft:通过建立多层Raft群组,旨在改善跨地域的数据一致性和同步效率。
  3. Lease-based Raft:在Raft中引入租约机制以优化读操作,减少对Leader的依赖,提高读操作的性能。

尽管Raft有其局限,但它的简洁性和结构化决策使其在多种应用场景下仍然非常有效。选择合适的一致性协议应基于系统的具体需求和运行环境。

12. ParallelRaft

本人了解之后发现论文中一些细节阐述的其实不是很清晰,参考如下:

解读PolarFS中的Parallel Raft共识算法

PolarFS的ParallelRaft


http://www.kler.cn/news/336975.html

相关文章:

  • 开源2+1链动S2B2C商城小程序下社区团长的社群温度营造与商业价值实现
  • STM32 通用同步/异步通信
  • 基于SpringBoot图书馆预约与占座小程序【附源码】
  • JS测试框架——Jest
  • selenium元素定位
  • 仿小米的Disucz模板
  • TypeScript 算法手册【快速排序】
  • CSP-S复习:图论题选讲
  • 【网络安全】基础知识详解(非常详细)零基础入门到精通
  • Ubuntu24 Firefox和Window Firefox同步问题
  • 大厂程序员用AI能完成几个人的工作量?
  • 如何使用 Ansible 管理多阶段环境
  • 考研笔记之操作系统(四) - 文件管理
  • ESP8266模块的GPIO0引脚在不同工作模式下
  • PGMP-01概述2
  • Ubuntu 搭建 Gitea
  • dwceqos网络驱动性能优化
  • RT-Thread实时操作系统 动态线程的创立
  • Ollama 运行视觉语言模型LLaVA
  • 指针(7)