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

为什么 Raft 不会丢数据?

Raft 算法不会丢数据的核心原因,是通过 严格的日志复制规则、选举安全性约束、提交机制 三重保障,确保只有 “集群共识确认的数据” 才会被提交,且故障恢复后能精准恢复到一致状态。



一、日志复制:数据同步必须过半数确认

Raft 的写操作流程,从根源上杜绝了单机数据丢失的可能:

  1. 写请求只能走 Leader

    所有客户端的写操作,必须先发给 Leader,Follower 不接受写请求。

    Leader 收到请求后,会先把操作记录为一条 未提交的日志条目(包含 term 任期号、日志索引)。

  2. 同步日志到 Follower,必须过半数确认

    Leader 会把这条日志同步给所有 Follower,只有当 超过半数节点(包括 Leader 自己)成功复制了这条日志,Leader 才会将这条日志标记为 已提交

    • 数学保障:集群中任意两个 “过半数节点集合” 必然有交集 → 确保日志不会丢失。
    • 举例:3 节点集群,至少 2 个节点复制成功才算提交;5 节点集群,至少 3 个节点复制成功。
  3. 提交后才会响应客户端

    只有日志提交成功,Leader 才会执行具体的写操作(比如修改数据),并向客户端返回 “操作成功”。

    客户端收到成功响应时,数据已经在集群多数节点上存在了,就算 Leader 宕机,其他节点也有这份数据。




二、选举安全性:只有数据最新的节点才能当 Leader

这是 Raft 不丢数据的 最关键约束 —— 确保新 Leader 一定拥有集群中所有已提交的日志

选举的核心规则(必须满足 2 个条件)

当 Follower 因收不到 Leader 心跳而变成 Candidate 时,想要当选 Leader,必须满足:

  1. Candidate 必须获得超过半数节点的投票
  2. 投票节点只会把票投给 “日志比自己更新的 Candidate”。
    • 日志 “更新” 的判断标准:任期号更大 → 若任期号相同,则 日志索引更长

为什么这个规则能保证不丢数据?

  • 已提交的日志,必然存在于 超过半数节点 上。
  • Candidate 想要拿到超过半数的投票,就必须和这些 “持有已提交日志的节点” 的日志保持一致 → 否则拿不到票。
  • 最终当选的 Leader,必然包含集群中所有已提交的日志

反例:旧数据节点不可能当选 Leader

假设集群有 3 个节点(A=Leader, B、C=Follower):

  1. A 提交了一条日志(已同步到 B),但还没同步到 C 时,A 宕机。
  2. B 和 C 都会变成 Candidate,但 C 的日志比 B 旧。
  3. B 向 C 拉票时,C 发现 B 的日志更新 → 投给 B;B 自己也投自己 → 拿到 2 票(过半数),当选 Leader。
  4. C 会从新 Leader B 同步缺失的那条已提交日志 → 数据完整恢复。
  5. 若 A 后来重启,会发现 B 的日志更新 → 自动降级为 Follower,并同步 B 的日志 → 最终集群日志一致。




三、故障恢复:Follower 自动追平 Leader 日志

Raft 集群中,节点故障恢复后,会通过 日志一致性检查 自动同步缺失数据,确保集群状态一致:

  1. Leader 维护 nextIndex 指针

    Leader 会为每个 Follower 维护一个 nextIndex(表示下一次要发送给 Follower 的日志索引)。

  2. 日志不匹配时,Leader 回退重试

    当 Leader 发现 Follower 的日志和自己不一致时,会 回退 nextIndex,从更早的日志开始重新同步,直到找到双方一致的日志点,再把后续的日志全部同步给 Follower。

  3. 旧 Leader 降级同步

    故障的旧 Leader 重启后,会发现集群已有新 Leader,此时会自动降级为 Follower,并从新 Leader 同步最新日志 → 最终所有节点日志完全一致。



四、关键结论:Raft 不丢数据的 3 个承诺

  1. 已提交的数据绝不丢:客户端收到 “写成功” 响应时,数据已在多数节点存在,必然能被后续 Leader 继承。
  2. 未提交的数据可丢弃:如果 Leader 没等到多数节点确认就宕机,这条未提交的日志会被丢弃 —— 但客户端不会收到成功响应,业务层面感知不到(相当于写失败)。
  3. 集群始终一致:故障恢复后,所有节点最终会拥有完全相同的日志,不会出现数据分歧。



五、和 MySQL 主从的对比

很多人会把 Raft 和 MySQL 传统主从对比,核心区别在于 数据一致性保障

特性 Raft 算法 MySQL 传统主从(异步复制)
写入口 只有 Leader 可写 主库可写,从库只读
数据提交条件 过半数节点同步成功 主库写入成功即返回,从库异步复制
故障丢数据风险 无(已提交数据) 有(主库宕机时,未同步的从库会丢数据)
新主数据完整性 必然包含所有已提交数据 可能选到数据较旧的从库(需手动选 GTID 最新的)
http://www.jsqmd.com/news/650167/

相关文章:

  • 告别繁琐部署,PolarClaw SaaS 让 AI 应用管理触手可及
  • 上海喷漆加工工艺详解:从工序管控到品质提升
  • 5分钟掌握专业卡牌批量生成:CardEditor让你的桌游设计效率提升300%
  • QQ空间导出助手:一键备份青春回忆的完整解决方案
  • 项目flutter运行环境汇总
  • 用STC8G1K08单片机给TEA5767调频模块做个“傻瓜式”频率切换器(附源码和PCB)
  • 口碑好的板式换热器板片生产厂分享,员工专业的哪个靠谱 - 工业推荐榜
  • 逐段解读------深入理解计算机系统------1.7 操作系统管理硬件
  • 终极指南:5分钟快速上手canvas-editor开源富文本编辑器
  • 【架构实战】影刀 RPA 并发矩阵的“网络隔离”工程:动态代理调度与底层防关联架构
  • JPA save() 方法不生效?5个常见坑点及解决方案(附代码示例)
  • 3大核心技术场景:如何彻底解决开源插件跨平台兼容性难题?
  • JPEXS Free Flash Decompiler:开源Flash逆向工程工具的架构深度解析与实战指南
  • 3层加密防御:TigerVNC安全传输协议深度解析
  • Redis Pipeline 管道化性能分析
  • linux组权限
  • 3分钟快速汉化:Axure RP中文语言包完整使用指南
  • JConsole远程JMX连接实战:从零配置到安全策略详解
  • 告别繁琐手工!3分钟用CardEditor批量生成100张专业卡牌
  • League Akari:英雄联盟玩家的智能自动化实战指南
  • 基于C#与KepServer实现S7协议仿真通信的实践指南
  • Kivy项目实战:从Python代码到安卓APK的完整避坑记录(VirtualBox+打包镜像)
  • 解决ComfyUI自定义节点管理难题的终极方案:ComfyUI-Manager实战指南
  • 如何通过GSE高级宏编译器实现游戏操作自动化
  • 告别抓瞎!用CANoe CAPL玩转以太网:从链路状态监控到数据包深度解析实战
  • Fix-Kindle-Ebook-Cover终极指南:三步修复Kindle电子书封面损坏问题
  • APKMirror:安卓应用下载的终极免费安全指南 [特殊字符]
  • 2026年有实力的低温蜡水玻璃铸造生产商推荐,费用怎么收值得讲讲 - 工业设备
  • 2021SC@SDUSC Zxing开源代码(八)Data Matrix二维码编码原理与实现解析
  • NI设备维护必备技能:用MAX生成带校验时间的系统配置报告(避坑自定义报表加载问题)