《深入理解 Nacos 集群与 Raft 协议》系列三:日志对比机制:Raft 如何防止数据丢失与错误选主

《深入理解 Nacos 集群与 Raft 协议》系列

大家好,我是G探险者!

在第 2 篇中,我们讲解了 Raft 的选主过程。但单靠"投票数过半"并不能完全保障新 Leader 的安全性。

为了防止数据丢失和不合法的 Leader 被选出,Raft 引入了关键的 日志对比机制(Log Comparison)。这一机制确保:

只有拥有"最新日志"的节点才能当选 Leader。

那么,"最新"是如何判断的?这个机制是如何工作的?又是如何保障数据一致性的?我们逐一解析。


一、为什么投票不能只看任期?

设想一个场景:

  • 第 1 次提交时,A 是 Leader,ABC 同步成功
  • A 崩溃后,CDE 成为候选人集群
  • D 发起选主,但 D 的日志落后于之前提交的日志

如果这时 D 被选为 Leader,就会出现:

  • D 发起的 AppendEntries 会让 C 删除与其不同的日志项
  • 导致之前提交的日志被回滚,数据丢失!

这就是 "旧节点错误地成为 Leader" 导致的严重后果。

Raft 设计了日志对比机制来彻底避免这种情况。


二、日志对比的两个关键字段

当 Candidate 发起选举时,会在 RequestVote 请求中附带:

text 复制代码
lastLogIndex:最后一条日志的索引
lastLogTerm:最后一条日志的任期号

Follower 收到投票请求时,会进行判断:

候选人的日志是否"更新"?

判断规则如下:

  1. 谁的 lastLogTerm 大,谁的日志更新
  2. 如果 lastLogTerm 相同,则看 lastLogIndex 谁大

只有候选人日志"更新"时,Follower 才会投票。


三、为什么这样判断就足够安全?

这种机制保证了:

  • 所有当选的 Leader,日志一定不比大多数节点旧
  • 从而不会覆盖大多数节点上已经存在的日志

换句话说,新 Leader 必须包含"前任 Leader 已提交的日志"

这就实现了我们在第 1 篇中提到的:"每次提交的多数派之间必须有交集",从而实现日志递进一致性。


四、举个例子来理解日志对比

假设 5 个节点:A、B、C、D、E

  • A 是 Leader,提交了 index=3 的日志
  • 复制到了 ABC 节点

这时 A、B 宕机,C、D、E 存活。

  • D 发起选举,日志只到 index=1(旧)
  • C 拒绝投票,因为自己的 lastLogTerm/index 更新

→ D 选举失败,不能成为 Leader

接下来 C 发起选举,D、E 都投票 → 成功成为新 Leader

因为 C 拥有最完整的日志,才有资格成为 Leader。


五、Raft 如何保证最终一致性?

有了日志对比机制,Raft 能做到:

  • 选主只选"最新"的节点,防止数据倒退
  • 新 Leader 会用自己的日志覆盖旧节点的非一致日志
  • AppendEntries 中包含前一个日志的索引和任期,作为对齐基准

最终,每个节点的日志都会逐步和 Leader 保持一致。


六、在 Nacos 中的体现

你可以从以下场景中感受到日志对比的存在:

  • 节点日志落后,迟迟不能当选 Leader
  • 选主期间频繁看到日志校验失败的投票日志
  • 某节点刚启动,必须通过日志对齐后才成为稳定成员

这些机制背后,都是为了实现一致性的日志对比与对齐。


七、总结

Raft 的日志对比机制,是保障"选主安全性"和"日志最终一致性"的核心:

  • 投票时检查候选人日志是否比自己新
  • 防止日志回滚,避免脑裂与数据丢失
  • 所有新 Leader 都必须有前任 Leader 的提交副本

下一篇我们将继续讲解:

💡 Raft 日志是如何复制的?提交策略、确认机制与幂等性保障

敬请期待第 4 篇!

相关推荐
追逐时光者5 小时前
推荐 12 款开源美观、简单易用的 WPF UI 控件库,让 WPF 应用界面焕然一新!
后端·.net
Jagger_5 小时前
敏捷开发流程-精简版
前端·后端
苏打水com6 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
间彧7 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧7 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧7 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧7 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端
间彧7 小时前
Spring Cloud Gateway详解与应用实战
后端
EnCi Zheng8 小时前
SpringBoot 配置文件完全指南-从入门到精通
java·spring boot·后端
烙印6018 小时前
Spring容器的心脏:深度解析refresh()方法(上)
java·后端·spring