Raft如何做到线性一致性
一、为什么需要请求去重考虑一次Append(name, A)1. 客户端发送 Append 请求 2. Leader 将请求提交到 Raft 日志 3. KV 状态机执行成功name 变成 A 4. 服务端返回响应 5. 但响应在网络中丢失 6. 客户端超时重新发送同一个请求如果服务端无法识别重试Append会再次执行第一次执行name A 第二次执行name AA客户端实际上只请求了一次状态机却执行了两次这会破坏客户端期望的语义。因此必须给每个逻辑请求一个唯一身份。二、ClientId和CommandId分别是什么图中每个客户端维护两个重要信息。ClientId表示客户端身份例如客户端AClientId C1001 客户端BClientId C2001项目中Clerk创建时会生成客户端 ID并将请求序号初始化为 0Clerk::Clerk() : m_clientId(Uuid()), m_requestId(0), m_recentLeaderId(0) {}CommandId在项目中叫RequestId表示该客户端发出的第几个逻辑请求(C1001, 1) - Put(x, A) (C1001, 2) - Append(x, B) (C1001, 3) - Get(x)每次产生一个新的逻辑请求时客户端将m_requestId加一m_requestId; auto requestId m_requestId;三、为什么必须是二元组唯一请求标识是(ClientId, RequestId)不能只使用ClientId因为一个客户端会发送很多请求。不能只使用RequestId因为不同客户端都可能存在RequestId 1(C1001, 1) (C2001, 1)这显然是两个不同请求。因此ClientId RequestId共同构成一个类似“幂等键”的东西。项目中的 Raft 命令Op包含这两个字段class Op { public: std::string Operation; std::string Key; std::string Value; std::string ClientId; int RequestId; };四、重试时 RequestId 不能增加这是图中非常关键的一点。新的逻辑请求才增加RequestId第一次业务操作RequestId 10 第二次业务操作RequestId 11同一个请求因为超时而重试时必须继续使用原来的 ID发送请求(C1001, 11) 超时重试(C1001, 11) 再次重试(C1001, 11)不能变成 12、13否则服务端会认为它们是三个不同请求。这个项目做得是对的requestId在进入重试循环之前保存循环中始终复用它m_requestId; auto requestId m_requestId; while (true) { args.set_requestid(requestId); // 向不同服务器重试 }五、服务端如何判断重复请求每个 KV Server 保存std::unordered_mapstd::string, int m_lastRequestId;含义是ClientId - 该客户端已经执行过的最大 RequestId例如C1001 - 15 C2001 - 8表示C1001的 1 到 15 号请求已经处理过。判断重复请求的逻辑是return RequestId m_lastRequestId[ClientId];假设m_lastRequestId[C1001] 15那么请求 16新请求可以执行 请求 15重复请求不能再次执行 请求 14旧请求也不能再次执行这就是图中“只执行递增的 CommandId”的具体含义。六、完整的丢包重试过程客户端 C7 发送 (C7, 12, Append(x, A)) Leader 写入 Raft 日志 ↓ 多数节点复制成功 ↓ 日志被提交 ↓ KV 状态机执行 Append ↓ lastRequestId[C7] 12 ↓ 响应丢失 ↓ 客户端重试同一个 (C7, 12) ↓ 服务端发现 12 lastRequestId[C7] ↓ 不再执行 Append直接返回成功项目在 Raft 提交命令后调用ifRequestDuplicate()只有非重复请求才操作 KV 数据if (!ifRequestDuplicate(op.ClientId, op.RequestId)) { if (op.Operation Put) { ExecutePutOpOnKVDB(op); } if (op.Operation Append) { ExecuteAppendOpOnKVDB(op); } }执行 KV 操作时还会更新m_lastRequestId[op.ClientId] op.RequestId;KV 状态和去重信息在同一把互斥锁保护下更新这一点很重要。七、它与线性一致性的关系线性一致性要求每个操作看起来都在某一个瞬间原子完成而且不能违反真实时间顺序。Raft主要解决所有节点按照相同的日志顺序执行命令请求去重解决客户端的一次逻辑操作即使多次重试也只产生一次状态变化二者缺一不可。例如没有去重时Raft可能完全正确地提交两条相同的Append日志。Raft不知道它们是同一次请求的重试因为对 Raft 来说它们只是两条合法命令。所以更准确地说Raft提供一致的提交顺序ClientId RequestId提供重试情况下的至多一次执行语义二者共同支撑线性一致的客户端体验。网络层无法真正保证消息“只发送一次”这里只能保证重复消息不会导致状态机重复生效。

相关新闻

JWT解析工具

JWT解析工具

JWT令牌怎么解码查看?在线JWT解析工具教程 前后端分离项目中,JWT(JSON Web Token)是最常用的身份认证方式。但拿到一串 xxxxx.yyyyy.zzzzz 的 token,根本看不出里面存了什么信息、什么时候过期。本文教你用盘子工具站…

2026/7/31 9:43:11 阅读更多 →
OpenHarmony系统Python3.13.5移植实战指南

OpenHarmony系统Python3.13.5移植实战指南

1. 项目背景与挑战去年在为一个工业物联网项目选型时,客户要求必须在OpenHarmony系统上运行Python数据分析脚本。当时市面上还没有成熟的Python3移植方案,这直接促使我开始了将Python3.13.5移植到OpenHarmony的工作。OpenHarmony作为新一代分布式操作系统…

2026/7/31 9:43:11 阅读更多 →
不要问模型是 Transformer 还是 Diffusion:一套五层技术栈检查法(系统角色 / 表示空间 / 网络骨架 / 训练范式 / 推理算法)

不要问模型是 Transformer 还是 Diffusion:一套五层技术栈检查法(系统角色 / 表示空间 / 网络骨架 / 训练范式 / 推理算法)

不要问模型是 Transformer 还是 Diffusion:一套五层技术栈检查法 摘要 Transformer、VAE、Diffusion、Flow 和 Solver 经常被放在同一张比较表里,但它们回答的是不同问题。本文建立系统角色、表示空间、网络骨架、训练/生成范式和推理算法五层检查法&…

2026/7/31 9:43:11 阅读更多 →

最新新闻

游戏抽卡系统设计:从权重随机到概率补偿的完整技术方案

游戏抽卡系统设计:从权重随机到概率补偿的完整技术方案

最近在游戏社区里,一个看似简单的抽卡机制却让不少玩家又爱又恨——明明想要"猫猫糕",结果抽到的却是"兔兔菇";好不容易攒够资源抽"菇菇兔",却总是与心仪角色擦肩而过。这种随机性带来的挫败感&…

2026/7/31 10:19:22 阅读更多 →
Java构建前端可视化维度指标列表的实践与优化

Java构建前端可视化维度指标列表的实践与优化

1. 项目概述:Java构建前端可视化维度指标列表的核心价值在数据驱动的现代应用开发中,可视化维度指标列表已成为管理后台、数据分析平台和运营系统的标配组件。作为全栈开发中的关键环节,用Java构建这类组件需要兼顾后端数据处理效率和前端展示…

2026/7/31 10:19:22 阅读更多 →
PDF文档差异对比神器:diff-pdf完整使用指南

PDF文档差异对比神器:diff-pdf完整使用指南

PDF文档差异对比神器:diff-pdf完整使用指南 【免费下载链接】diff-pdf A simple tool for visually comparing two PDF files 项目地址: https://gitcode.com/gh_mirrors/di/diff-pdf 还在为PDF版本对比而烦恼吗?每次收到修订后的文档&#xff0c…

2026/7/31 10:19:22 阅读更多 →
Vue3系统性学习指南:从核心基础到高级实战

Vue3系统性学习指南:从核心基础到高级实战

1. 项目概述:为什么现在必须系统性学习Vue3?如果你是一名前端开发者,或者正打算从前端入门,那么“Vue3”这个词在过去两年里一定反复出现在你的视野里。从2020年9月正式发布到现在,Vue3已经不再是那个需要观望的“新版…

2026/7/31 10:19:22 阅读更多 →
KMP算法核心:PM、next与nextval数组详解与手算指南

KMP算法核心:PM、next与nextval数组详解与手算指南

1. 项目概述:从“草履虫”视角看串的模式匹配如果你正在学习数据结构,尤其是学到“串”这一章,看到KMP算法里那三个长得像亲兄弟一样的数组——PM、next和nextval——感觉脑子快打结了,那么恭喜你,你来对地方了。我当年…

2026/7/31 10:19:22 阅读更多 →
实战指南:在 openEuler 上部署 MySQL + LangChain AI 数据库查询工具

实战指南:在 openEuler 上部署 MySQL + LangChain AI 数据库查询工具

任务要求 部署 openEuler 服务器,关闭 SELinux、配置可用 yum 源,编译安装 Python3.11.9; 安装 MySQL8.0.45,创建 testdb 库、order_info 订单业务表,导入20 条标准测试订单数据; 登录并开通腾讯云 TokenHu…

2026/7/31 10:18:21 阅读更多 →

日新闻

物理复制比逻辑复制好在哪?数据库复制原理详解

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:00:34 阅读更多 →
BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:00:34 阅读更多 →
有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:00:34 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/31 4:19:39 阅读更多 →

月新闻