分布式算法raft系列(3)-日志复制

1. 日志结构

  • 每个节点维护一个日志,日志由条目组成,每个条目包含:
    • 命令:客户端提交的操作。
    • 任期号:记录创建该条目的领导者的任期。
    • 索引:日志条目在日志中的位置。
  • 日志分为已提交(Committed)和未提交(Uncommitted)两部分,只有多数节点复制的日志条目才会被提交。

2. 日志复制流程

领导者负责接收客户端请求并将操作复制到所有跟随者节点,具体步骤如下:

  1. 接收客户端请求
    • 客户端将命令发送给领导者。
    • 领导者将命令追加到自己的日志中,作为一个新的日志条目(包含当前任期号和索引)。
  2. 发送日志条目
    • 领导者通过AppendEntries RPC消息将日志条目发送给所有跟随者,消息包含:
      • 领导者的任期号。
      • 前一个日志条目的索引和任期号(用于一致性检查)。
      • 新日志条目内容。
      • 领导者的当前提交索引(Commit Index)。
  3. 跟随者处理
    • 跟随者接收到AppendEntries消息后:
      • 检查消息中的任期号:如果领导者的任期号小于自己的任期号,拒绝请求。
      • 检查一致性:验证前一个日志条目的索引和任期号是否与本地日志匹配。
      • 如果一致,跟随者将新条目追加到本地日志,并回复成功。
      • 如果不一致,跟随者拒绝请求,并告知领导者不匹配的索引。
  4. 领导者处理响应
    • 如果多数跟随者成功复制了日志条目,领导者将该条目标记为已提交(更新Commit Index)。
    • 领导者在后续的AppendEntries消息中通知跟随者已提交的索引。
    • 跟随者收到提交索引后,将对应日志条目应用到自己的状态机(State Machine)。
  5. 心跳机制
    • 领导者定期发送心跳消息(空的AppendEntries消息),用于维持权威并防止跟随者触发新选举。
    • 心跳消息也包含提交索引,帮助跟随者更新已提交日志。

3. 一致性检查与日志修复

  • 如果跟随者的日志与领导者不一致(例如,由于网络分区或故障),领导者通过以下方式修复:
    • 领导者收到拒绝响应后,递减发送的前一个日志索引,重试AppendEntries,直到找到跟随者日志的匹配点。
    • 找到匹配点后,领导者将后续日志条目发送给跟随者,覆盖不一致的部分。
  • 这一过程确保跟随者的日志最终与领导者一致。

4. 提交与应用

  • 只有当日志条目被复制到多数节点后,领导者才将其标记为已提交。
  • 已提交的日志条目会被领导者和跟随者应用到状态机,确保所有节点的状态一致。
  • RAFT保证已提交的日志不会被回滚(Leader Completeness属性)。

5. 异常处理

  • 领导者故障:如果领导者崩溃,跟随者会在选举超时后触发新选举。新领导者当选后,继续日志复制,可能覆盖旧领导者的未提交日志。
  • 网络分区:如果跟随者与领导者失联,领导者继续尝试发送AppendEntries。一旦重新连接,跟随者的日志会通过一致性检查与领导者同步。
  • 日志冲突:新领导者当选后,可能发现某些节点的日志包含未提交的条目。通过日志复制,新领导者会强制覆盖这些不一致的日志。

6. 优化

  • 批量复制:领导者通常一次发送多个日志条目,提高效率。
  • 流水线复制:领导者可以在收到确认前继续发送后续日志条目,减少延迟。
  • 快照(Snapshot):当日志过长时,节点会创建状态机快照,删除旧日志,降低存储和传输开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值