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

raft协议中一条数据写入流程

Raft 是一种分布式一致性协议,用于在多个节点之间达成一致状态,特别适用于分布式系统中管理日志复制和领导选举。以下是 Raft 协议中写入数据的详细流程,涵盖了从客户端请求到数据最终在集群中达成一致的步骤。我会尽量清晰地描述每个阶段,并结合 Raft 的核心概念(如领导者、日志复制和提交)。


Raft 协议写入数据的流程

在 Raft 中,写入数据实际上是通过日志(log)追加和复制来实现的。整个流程依赖于领导者(Leader)、跟随者(Follower)和候选者(Candidate)三种角色,其中领导者负责协调写入操作。以下是详细步骤:

1. 客户端发送写入请求
  • 前提:Raft 集群中已选举出一个唯一的领导者(Leader)。客户端只会与领导者交互。
  • 操作:客户端向领导者发送一个写入请求,例如“将值 X 写入键 K”。
  • 细节:请求通常包含操作命令(command),例如键值对的更新。
2. 领导者追加日志条目
  • 操作:领导者接收到客户端请求后,将该操作封装为一个日志条目(log entry),追加到自己的本地日志中。
  • 日志条目内容
    • 索引(Index):日志条目的位置(从 1 开始递增)。
    • 任期(Term):领导者当前所在的任期号,用于确保一致性。
    • 命令(Command):客户端的写入操作(例如 set K=X)。
  • 状态:此时日志条目是“未提交”(uncommitted),仅存在于领导者的日志中。
  • 示例
    • 假设领导者当前任期为 3,日志索引为 5,客户端请求 set K=X,则追加的日志条目为:{index: 5, term: 3, command: set K=X}。
3. 领导者向跟随者复制日志
  • 操作:领导者通过网络将新日志条目发送给所有跟随者(Followers),使用 AppendEntries RPC(追加条目远程过程调用)。
  • AppendEntries RPC 内容
    • 新日志条目(index, term, command)。
    • 前一个日志的索引和任期(prevLogIndex, prevLogTerm):用于验证跟随者的日志是否与领导者一致。
    • 提交索引(commitIndex):领导者当前已提交的日志索引。
  • 目标:确保所有节点的日志最终与领导者的日志一致。
  • 细节
    • 领导者并行发送请求给所有跟随者。
    • 每次 RPC 还包含心跳信息,用于维持领导者地位。
4. 跟随者接收和验证日志
  • 操作:每个跟随者接收到 AppendEntries 请求后:
    1. 一致性检查
      • 检查 prevLogIndex 和 prevLogTerm 是否与自己的日志匹配。
      • 如果匹配,追加新日志条目;如果不匹配,拒绝请求并通知领导者。
    2. 追加日志
      • 如果检查通过,跟随者在本地日志中追加新条目。
    3. 响应领导者
      • 返回成功或失败的响应。
  • 示例
    • 跟随者日志已有 {index: 4, term: 3},收到 {prevLogIndex: 4, prevLogTerm: 3, entry: {index: 5, term: 3, command: set K=X}},则追加成功。
    • 如果跟随者日志缺失或任期不匹配,则拒绝。
5. 领导者等待多数派响应
  • 操作:领导者等待集群中超过半数节点(即多数派,quorum)的确认。
    • Raft 的核心一致性保证:只要多数节点成功复制了日志条目,该条目就可以安全提交。
  • 规则
    • 对于包含 N 个节点的集群,多数派需要至少 (N/2) + 1 个节点。
    • 示例:5 节点集群需要 3 个节点确认。
  • 结果
    • 如果收到多数派成功响应,领导者标记该日志条目为“已提交”(committed)。
    • 如果未达到多数派(例如网络分区或节点故障),写入失败,客户端会收到超时或错误。
6. 领导者提交日志并应用到状态机
  • 操作
    • 领导者将日志条目的状态更新为“已提交”。
    • 将命令应用到本地状态机(state machine),例如更新键值存储中的 K=X。
  • 更新提交索引
    • 领导者更新自己的 commitIndex 为最新提交的日志索引(例如 5)。
  • 通知客户端
    • 领导者向客户端返回成功响应,例如“写入完成”。
7. 领导者通知跟随者提交
  • 操作:领导者在下一次 AppendEntries RPC(或心跳)中通知所有跟随者更新其 commitIndex。
  • 跟随者行为
    • 接收到新的 commitIndex 后,将对应的日志条目标记为“已提交”。
    • 将命令应用到自己的状态机,保持与领导者一致。
  • 细节
    • 即使某些跟随者之前未收到日志条目,领导者会持续重试,确保最终一致性。
8. 确保一致性(异常处理)
  • 日志不一致
    • 如果跟随者的日志与领导者不一致(例如缺失条目或任期冲突),领导者会回溯 prevLogIndex,发送更早的日志条目,直到找到一致点,然后覆盖跟随者的日志。
  • 领导者故障
    • 如果领导者在提交前宕机,新选举的领导者会检查日志并继续未完成的工作。
    • 未提交的条目可能被新领导者丢弃(取决于多数派是否已复制)。

完整流程图(文字版)

  1. 客户端 -> 领导者:发送写入请求 set K=X。
  2. 领导者:追加日志条目 {index: 5, term: 3, command: set K=X}。
  3. 领导者 -> 跟随者:发送 AppendEntries RPC。
  4. 跟随者:验证并追加日志,返回响应。
  5. 领导者:收到多数派响应,标记日志为“已提交”。
  6. 领导者:应用命令到状态机,返回成功给客户端。
  7. 领导者 -> 跟随者:通过心跳通知提交。
  8. 跟随者:应用已提交日志到状态机。

关键特性

  • 强一致性:只有多数节点确认后,数据才算提交。
  • 容错性:只要多数节点存活,集群仍可工作。
  • 日志复制:通过日志确保所有节点状态最终一致。
  • 领导者单点:所有写入必须经过领导者,避免冲突。

示例场景(5 节点集群)

  • 初始状态:领导者日志 [1:T1, 2:T1, 3:T2, 4:T3],跟随者同步。
  • 写入请求:客户端发送 set K=X。
  • 步骤
    1. 领导者追加 [5:T3: set K=X]。
    2. 发送 AppendEntries 给 4 个跟随者。
    3. 3 个跟随者成功响应(加上领导者自己,共 4 个,超过半数)。
    4. 领导者提交 [5:T3],应用 K=X,通知客户端。
    5. 后续心跳通知其他跟随者提交。

注意事项

  • 性能:写入需要等待多数派响应,延迟可能高于单节点系统。
  • 网络分区:如果领导者与多数节点失联,写入会暂停,直到新领导者选举成功。
  • 日志压缩:长期运行需要日志压缩(如快照),否则日志会无限增长。

总结

Raft 协议的写入流程是通过领导者协调日志追加、复制和提交完成的。核心是利用 AppendEntries RPC 和多数派确认机制,确保数据一致性和容错性。

http://www.dtcms.com/a/113534.html

相关文章:

  • Java 实现插入排序:[通俗易懂的排序算法系列之三]
  • 文献总结:TPAMI综述BEV感知—Delving into the devils of bird‘s-eye-view perception
  • Socket编程TCP
  • HarmonyOS:WebView 控制及 H5 原生交互实现
  • 硬件学习之器件篇-蜂鸣器
  • 第三章 react redux的学习之redux和react-redux,@reduxjs/toolkit依赖结合使用
  • use_tempaddr 笔记250405
  • setj集合
  • 1.5 基于改进蛇优化VGG13SE故障诊断方法的有效性分析
  • Python实现链接KS3,并将文件数据上传到KS3
  • 【spring Cloud Netflix】OpenFeign组件
  • 第二十九章:Python-mahotas库:图像处理的高效工具
  • 使用 pytest-xdist 进行高效并行自化测试
  • PHP的垃圾回收机制
  • 我的创作历程:从不情愿到主动分享的成长
  • 用北太天元脚本解决了关于双曲线的求离心率对应的参数、等腰三角形条件下的点坐标和向量点积条件下的参数范围
  • 如何判断栈生长的方向
  • SDL显示YUV视频
  • 快速从零部署一个DeepSeek-R1服务
  • NAS原理与技术详解:从基础概念到实践应用
  • 基础知识补充篇:关于数据不可修改
  • 功能测试和性能测试的区别有哪些?
  • 使用Geotools中的原始方法来操作PostGIS空间数据库
  • java高并发------守护线程Daemon Thread
  • Redis数据结构之ZSet
  • P3654 First Step (ファーストステップ)
  • Linux:(五种IO模型)
  • 基于SSM的高校宿舍水电管理系统
  • 0201线性回归-机器学习-人工智能
  • 开篇 - 配置Unlua+VsCode的智能提示、调试以及学习方法