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

《深入理解 Nacos 集群与 Raft 协议》系列四:日志复制机制:Raft 如何确保提交可靠且幂等

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

大家好,我是G探险者!

在前几篇中我们介绍了选主与日志对比机制,它们保证了“谁能成为 Leader”以及“Leader 的日志是否可靠”。

而当 Leader 已选定,系统需要把客户端的写请求写入所有节点的日志中,这个过程就称为 日志复制(Log Replication)

本篇将讲解:

  • Raft 是如何进行日志复制的?
  • 如何判断日志是否成功提交?
  • 如何保障幂等与一致性?

一、基本流程:写入 Leader,然后复制给 Follower

在 Raft 中,所有写操作必须提交到 Leader 节点,流程如下:

  1. 客户端发送写请求给 Leader
  2. Leader 将写请求封装为日志条目(LogEntry)
  3. Leader 将该日志追加到本地日志中
  4. 并并发向所有 Follower 发送 AppendEntries 请求
  5. Follower 收到后尝试匹配前一条日志(前向一致性)
  6. 匹配成功后,Follower 追加日志,并回复成功
  7. Leader 收到超过半数节点确认后 → 标记日志为“已提交”
  8. Leader 通知 Follower 提交该日志(commit)
  9. Leader 应用日志到状态机并响应客户端

整个过程看似复杂,但每一步都有其必要性。


二、什么是日志“提交”成功?

Raft 中,一条日志被称为“已提交”,必须满足:

该日志由 Leader 追加,且已被超过半数节点确认持久化。

这样做的意义是:

  • 即使 Leader 崩溃,仍有过半节点持有该日志
  • 下次选主,一定会选出有这条日志的节点为新 Leader(见第 3 篇)

→ 已提交的日志,不会丢。


三、AppendEntries 的核心要素

AppendEntries 请求中包含:

  • leaderTerm:当前任期
  • prevLogIndex + prevLogTerm:前一日志索引+任期(对齐用)
  • entries:本次追加的日志条目(可能为空,仅用于心跳)
  • leaderCommit:Leader 当前提交的位置

Follower 会进行对比:

  • 若 prevLogIndex 和 prevLogTerm 不一致 → 拒绝请求
  • 否则 → 覆盖旧日志,从当前追加新日志

四、如何保证日志幂等?

在网络不稳定情况下,可能出现 AppendEntries 重发、乱序。

Raft 通过“前一条日志”对齐机制来保证幂等性:

  • 每次发送都携带 prevLogIndex/prevLogTerm
  • 若日志有误,Follower 会拒绝,Leader 自动回退并重发
  • 不会重复插入相同日志,也不会错位插入

→ 这是一种 乐观+校验补偿式的强一致写入机制


五、提交顺序与状态机执行

Raft 要求日志是顺序提交的:

  • 日志 index 是严格递增的
  • 必须 index=1 提交后才能提交 index=2

Leader 提交一条日志后:

  • 会逐步推进 commitIndex
  • Leader 会把 commitIndex 推送给所有 Follower
  • 每个 Follower 在收到时才会“真正执行”该日志到状态机

→ 所有节点最终状态机执行的日志是一致的、顺序的


六、断电/重启后如何恢复日志?

因为日志会持久化在本地磁盘上,所以:

  • Raft 节点宕机重启时,会从本地恢复日志
  • 并向新 Leader 进行日志对齐补偿

Raft 的一致性依赖于 持久化日志+对比同步机制,而非内存


七、日志复制在 Nacos 中的体现

你可以看到类似日志:

[RAFT] AppendEntries from leader, prevIndex=5, term=7
[RAFT] Log mismatch, conflict at index=5, localTerm=6
[RAFT] Truncate logs from index=5
[RAFT] Append new log entries...
[RAFT] Advance commitIndex to 8

这些就是日志对齐 + 复制 + 提交的全过程。


总结

Raft 的日志复制机制,是系统强一致性的核心支柱:

  • 所有写请求必须经 Leader 统一调度
  • 复制必须超过半数成功才算提交
  • 提交后才能执行,确保所有节点状态一致
  • Follower 校验 + 回退机制保证了幂等性

下一篇,我们将以 Nacos 为例讲解:

💡 如果集群未过半节点存活,为什么整个系统不可用?

敬请期待第 5 篇!

http://www.xdnf.cn/news/937711.html

相关文章:

  • 《Spring Boot 微服务架构下的高并发活动系统设计与实践》
  • CQF预备知识:Python相关库 -- SciPy 安装
  • 会计-合并-5- 处置交易在合报与个报会计处理
  • 由汇编代码确定switch语句
  • 第13次01:广告及商品数据呈现
  • (LeetCode 每日一题)386. 字典序排数(递归、深度优先搜索dfs || 递推)
  • 动态生成 PV 的机制:使用 NFS-Client Provisione
  • 深入解析Golang反射机制与高效文件操作实践
  • TCP相关问题 第一篇
  • Windows权限提升篇数据库篇MYSQLMSSQLORACLE自动化项目
  • 管理数据洪流:自动化处理与归档每日数据文件的策略与实践
  • BOM(Browser Object Model)核心对象手册
  • CNN核心机制深度解析:卷积池化原理 PyTorch实现经典网络
  • MSYS2 环境配置与 Python 项目依赖管理笔记
  • Z-FOLD: A Frustratingly Easy Post-Training Quantization Scheme for LLMs
  • MS39531N 是一款正弦驱动的三相无感直流电机驱动器,具有最小振动和高效率的特点
  • 深入理解 Java 的反射、注解与动态代理
  • 基于Python学习《Head First设计模式》第十章 状态模式
  • JavaScript数组扁平化(Array Flattening)全解析:从基础到进阶的9种实现方式及深度对比
  • C++.OpenGL (17/64)深度测试(Depth Testing)
  • Python Wheel 打包基本原理详解
  • LangChain工具集成实战:构建智能问答系统完整指南
  • RoboDK 自定义机器人
  • 当前市场环境下,软件行业的突围之道:技术演进与商业模式重构
  • 工厂方法模式和抽象工厂方法模式的battle
  • 135. 分发糖果
  • 【P2P】直播网络拓扑及编码模式
  • 【2025年6月8日】Claude 4 国内使用全攻略
  • 【优选算法】模拟 问题算法
  • CompletableFuture+线程池使用案列