Raft中乱序AppendEntries的处理:工业级实现方案问询
先明确问题场景:
《Raft论文》规定:AppendEntries规则为若现有日志条目与新条目冲突(索引相同但任期不同),则删除现有条目及其后续所有条目(§5.3)。从领导者视角,先发送含条目[1, 2]的AppendEntries请求,后发送含[1, 2, 3]的请求;而从跟随者视角,先收到含[1, 2, 3]的请求并成功追加,后续收到含[1, 2]的请求,按论文规则需删除条目[3]。但论文未提及乱序AppendEntries的处理方式,请问工业级Raft实现如何解决该问题?
工业级实现主要通过以下几种方式解决这个问题:
强化请求前置校验,过滤过期请求
跟随者收到AppendEntries请求时,会先做两项关键校验:一是检查请求中的领导者任期号,如果该任期号小于自身已知的当前有效领导者任期,直接拒绝请求;二是校验请求携带的prevLogIndex和prevLogTerm,同时对比自身日志的当前长度——比如场景中跟随者已经有[1,2,3],旧请求的日志终点是2,此时跟随者能判断出自身日志已经比请求要同步的进度更超前,直接返回拒绝响应,不会触发日志删除。保护已提交的日志条目
Raft协议的核心保证之一是已提交的日志不会被回滚,工业级实现会严格执行这一点:如果请求要求删除的日志条目已经被集群提交(比如[3]已经被多数节点确认提交),跟随者会直接拒绝该请求,绝不会执行删除操作。跟踪领导者的日志进度,识别乱序请求
多数实现会让跟随者维护对当前领导者日志进度的跟踪(比如记录领导者的nextIndex),当收到的AppendEntries请求的日志范围明显落后于该进度时,直接判定这是一个过期的乱序请求,直接丢弃,不做任何日志修改。
内容的提问来源于stack exchange,提问作者Jw C

