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

《深入理解 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 篇!

相关文章:

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

《深入理解 Nacos 集群与 Raft 协议》系列 大家好,我是G探险者! 在前几篇中我们介绍了选主与日志对比机制,它们保证了“谁能成为 Leader”以及“Leader 的日志是否可靠”。 而当 Leader 已选定,系统需要把客户端的写请求写入所…...

大模型如何选型?嵌入模型如何选型?

欢迎来到啾啾的博客🐱。 记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。 有很多很多不足的地方,欢迎评论交流,感谢您的阅读和评论😄。 目录 引言模型优劣认知与模型选择大模型(L…...

float转换为整型过程中关于小数部分的处理

在大多数编程语言中,将 float 类型转换为整型时,小数部分不会自动进行四舍五入,而是会直接截断(即丢弃小数部分,仅保留整数部分)。具体行为可能因语言而异,以下是常见语言的示例: 1.…...

开源大模型网关:One API实现主流AI模型API的统一管理与分发

以下是对One API的简单介绍: One API是一个使用go语言开发的大语言模型 API 管理与分发系统支持Docker一键快速部署,且资源占用小,高性能开箱支持多平台大模型快速接入,包括OpenAI、Gemini、xAI、Grop、Anthropic Claude、Ollama…...

Java线程工厂:定制线程的利器

在Java中,线程工厂(Thread Factory)是一个创建新线程的工厂。它提供了一种方式,允许你在创建线程时定制线程的属性,比如设置线程名称、线程的优先级、守护线程属性等。 线程工厂的主要目的是将线程的创建逻辑从使用线…...

智慧充电:新能源汽车智慧充电桩的发展前景受哪些因素影响?

全球能源结构转型与碳中和目标的推进,新能源汽车产业迎来爆发式增长,而智慧充电桩作为其核心基础设施,发展前景备受关注。智慧充电不仅关乎用户充电体验的优化,更是电网平衡、能源效率提升的关键环节。 然而,其发展并…...

在Pnetlab6上绕过TPM、安全启动和 RAM 检查安装windows 11笔记

笔者本次安装的windows11的镜像为: zh-cn_windows_11_enterprise_ltsc_2024_x64_dvd_cff9cd2d.iso 1、创建镜像目录并上传iso文件 mkdir /opt/unetlab/addons/qemu/win-win11x64-2024-LTSC //目录名称务必按照官方文档格式,否则无法识别 目录创建完成后,将.iso格式镜像上…...

【网站建设】不同类型网站如何选择服务器?建站项目实战总结

做了几个建站项目后,深刻体会到一件事:不同类型的网站,所采用的服务器策略是完全不同的。 如果选错了服务器方案,可能带来过高的成本、过低的性能,甚至上线失败。 这篇文章分享一下我在实战中的经验,供正在做建站项目的朋友参考。 🚩 1️⃣ 纯展示型网站 —— 静态服务…...

利用Pandas AI完成Excel大模型的结合实现自然语言问数

需求说明 实现对Excel工具的自然语言问数,即可以通过界面上传Excel文件,然后在文本框里通过语言对话的形式问出要统计的内容。比如: 用户数有多少? 语文成绩低于90的用户有多少? ..... 实现思路 Pandas AI是基于…...

iptables实验

实验一:搭建web服务,设置任何人能够通过80端口访问。 1.下载并启用httpd服务器 dnf -y install httpd 开启httpd服务器 systemctl start httpd 查看是否启用 下载并启用iptables,并关闭firewalld yum install iptable…...

前后端分离开发 和 前端工程化

来源:黑马程序员JavaWeb开发教程,实现javaweb企业开发全流程(涵盖SpringMyBatisSpringMVCSpringBoot等)_哔哩哔哩_bilibili 前后端混合开发: 需要使用前端的技术栈开发前端的功能,又需要使用Java的技术栈…...

web端rtmp推拉流测试、抽帧识别计数,一键式生成巡检报告

本文旨在实现无人机城市交通智慧巡检中的一个模块——无人机视频实时推拉流以及识别流并在前端展示,同时,统计目标数量以及违停数量,生成结果评估,一并发送到前端展示。对于本文任何技术上的空缺,可在博主主页前面博客…...

Excel 表格内批量添加前缀与后缀的实用方法

我们经常需要为 Excel 表格中的内容统一添加前缀或后缀,例如给编号加“NO.”、给姓名加“会员_”等。手动操作效率低,本文将介绍几种实用的方法,帮助你快速完成批量添加前缀和后缀的操作。 使用“&”运算符添加前缀或后缀(推…...

Vulkan 3D Tiles渲染器开发笔记1-脚手架搭建

一、项目简介 项目技术栈 CesiumNative + Dear ImGui + Vulkan 1.3 三维地理可视化系统 详细项目功能说明 1. 3DTiles渲染功能 实现完整的3DTiles格式解析与加载引擎支持LOD(Level of Detail)分层细节渲染可加载建筑模型、点云等3DTiles资产示例:加载城市级建筑3DTiles数据…...

2024 CKA题库+详尽解析| 15、备份还原Etcd

目录 免费获取题库配套 CKA_v1.31_模拟系统 15、 备份还原Etcd 题目: 开始操作: 1)、切换集群 2)、登录master并提权 3)、备份Etcd现有数据 4)、验证备份数据快照 5)、查看节点和Pod状态 6&am…...

【C/C++】std::vector成员函数清单

文章目录 std::vector使用指南1 不同版本提供的能力基础:C98 / C03 提供的成员函数C11 新增的成员函数C14:基本无变化(主要是标准库泛化,非 vector 成员变化)C17 引入的新特性(间接影响)C20 新增…...

如何借助Hyper - V在Windows 10中构建安全软件测试环境

视频演示 手把手教你激活 Hyper-V 并安装 Windows 10 虚拟机 一、引言:软件探索的风险与解决方案 在数字化时代,软件更新换代的速度日新月异,对于热衷于探索新软件的朋友而言,主系统中安装新软件时的谨慎态度无可厚非。恶意软件的威胁犹如高悬的达摩克利斯之剑,稍不留…...

西门子 S7-1200 PLC 海外远程运维技术方案

西门子 S7-1200 PLC 海外远程运维技术方案 一、面向海外场景的核心优势 针对跨国企业、海外项目及远程技术支持需求,本方案基于巨控GRM552Y-CHE模块提供无缝的全球化远程PLC运维能力,突破地域及时差限制,显著提升国际项目响应效率。 二、海…...

如何对Video视频进行SEO优化?

如何对Video视频进行SEO优化? 在现代互联网的海洋中,搜索引擎优化(SEO)无疑是每一个网站管理员和内容创作者必须掌握的技能。而今天,我要向大家介绍一个极为强大的工具——Schema.org。它不仅能提升你的网站在搜索引擎…...

嵌入式学习--江协stm32day5

USART 1. 引脚与接口层 异步引脚: TX:发送数据输出;RX:接收数据输入;SW_RX:单线半双工模式的接收引脚(替代 RX)。 同步引脚:SCLK:同步模式下的时钟输出&…...

(LeetCode 动态规划(基础版))96. 不同的二叉搜索树 (递推 || 递归)

题目:96. 不同的二叉搜索树 思路:二叉树长度为n时,枚举每个点u作为根节点root,那么root左边的数构成左子树种数left,root右边的数构成右子树种数right,那么当前u为根节点下,二叉树的种数为left*…...

服务器中CC攻击的特点有哪些?

CC攻击作为一种常见的网络攻击类型,主要是用来攻击网站页面的,当大量的用户在访问网站的过程中,打开页面的速度会变得比较慢,给数据库造成的压力就越大,CC攻击会消耗大量的服务器资源,给企业带来一定的经济…...

vue项目使用svg图标

下面是在 Vue 3 项目中完整引入和使用 vite-plugin-svg-icons 的步骤 1、安装插件 npm install vite-plugin-svg-icons -D # 或 yarn add vite-plugin-svg-icons -D # 或 pnpm add vite-plugin-svg-icons -D 2、配置 Vite 在 vite.config.ts 或 vite.config.js 中配置&…...

智能网卡之hinic3 WQE(Work Queue Element)结构梳理

hinic3 WQE(Work Queue Element)结构详解 本文基于 hinic3 驱动源码,对 WQE(Work Queue Element)做详细讲解。如需查阅完整源码和结构体定义可参考hinic3_nic_qp.h等文件。 1. WQE 的作用 WQE(Work Queue…...

go的工具库:github.com/expr-lang/expr

github.com/expr-lang/expr 是一个 Go 语言的表达式求值库,它允许你在运行时安全地执行表达式。主要用途包括: 1.表达式求值: program, err : expr.Compile("2 2") if err ! nil {// 处理错误 } result, err : expr.Run(program…...

力扣HOT100之二分查找:4. 寻找两个正序数组的中位数

这道题如果没有时间复杂度的限制的话,相当好做,但是这道题要求时间复杂度为O(log(m n)),思路很难想,我看了一圈题解,发现华南溜达虎的视频讲得还不错,我是参考他的思路写出来的,这里把他的思路…...

PyTorch——损失函数与反向传播(8)

Loss Functions 越小越好 L1loss MSELoss 损失函数 CrossEntyopyLoss 损失函数 import torch from torch.nn import L1Loss from torch import nn# 创建输入和目标张量,用于后续的损失计算 inputs torch.tensor([1,2,3],dtypetorch.float32) targets torch.tenso…...

macOS 升级 bash 到最新版本

macOS 的默认「终端」,千年不变的版本。 》〉bash --version GNU bash, version 3.2.57(1)-release (arm64-apple-darwin24) Copyright (C) 2007 Free Software Foundation, Inc. 官方 bash.git - bash 已经将 bash 升级到了 5.2的大版本。 macOS 最新版系统的 ba…...

Linux下如何查看一个端口被什么进程占用? 该进程又打开了哪些文件?

Linux下如何查看一个端口被什么进程占用&#xff1f; 该进程又打开了哪些文件&#xff1f; 查看端口 1.使用lsof命令查看端口占用的进程 lsof可以列出系统上打开的文件&#xff0c;其中包括网络连接、进程信息等。 lsof -i:<端口号> 例如&#xff0c;如果需…...

力扣面试150题--课程表

Day 63 题目描述 做法 初次思路&#xff1a;本质就是将所有前置课程和后置课程作为一个有向图&#xff08;前者指向后者&#xff09;&#xff0c;判断这个图是否是一个有向无环图&#xff08;即是否存在拓扑排序&#xff09;&#xff08;本质做法是dfs&#xff09; 做法&…...