直接回答:leader 把日志条目追加到本地并发给 follower,条目被复制到多数派后标记 committed 并应用到状态机,commit 位置随后续心跳广播。安全性的精确表述:一旦某条日志在任期 T 被提交,后续任期的 leader 必然包含它——由选举限制(投票者拒绝日志更旧的候选)加提交规则(leader 只能直接提交本任期日志)共同保证。
展开解析:经典坑的完整故事:老 leader 把条目复制到 2/5 节点后挂掉,新 leader(来自另外 3 节点)没有该条目——如果新 leader 允许“按复制计数提交旧任期条目”,该旧条目可能被后来的多数派覆盖,已提交假象破灭。Raft 的解法:leader 只对本任期的条目用计数提交,旧任期条目靠随后本任期条目(通常是一条 no-op)的提交间接收尾——“前任期日志间接提交”是 Raft 面试的深水区。脑裂行为推演:5 节点分成 2+3,老 leader 在 2 侧,它继续自认 leader 但任何写入拿不到多数派,永不提交——客户端在该分区的写请求超时;3 侧选出新 leader 正常服务;分区愈合后老 leader 收到更高 term 心跳立即退位,自己在分区期间未提交的日志被覆盖(一致性检查 AppendEntries 的 prevLogIndex/prevLogTerm 不匹配触发回退重写)。工程观察指标:commitIndex 与 applied 的差距、AppendEntries 失败率(日志不一致的征兆)、选举频率。对比记忆:Raft 用“强 leader”简化——日志只从 leader 流向 follower,冲突以 leader 为准,这是它比 Paxos 好懂的结构性原因。
追问方向:为什么需要 no-op 条目收尾?日志压缩(snapshot)如何与复制交互?
(约 500 字)