保持一致性
正常操作期间,Leader和followers的log保持一直。所以AppendEntries一致性检查从来不会失败,但是Leader总会有宕机的时候,就会导致日志记录不一致(以前的Leader可能没有完全复制所有的条目到他的日志里)。这些不一致会在一系列的Leader和follower的崩溃中加剧。
一个follower可能会错过leader发来的条目,也可能会有额外的条目,却不是来自leader的。或者两种情况同时存在与一个follower中,错失,和额外的条目可能会分成多个terms。
在Raft中,Leader处理非一致性是通过强迫follower的logs去复制Leader的log。就跟follower在git pull一样(不太准确,但行为比较好理解),如果不一致那就会有冲突,冲突的条目会来自Leader的log直接覆盖,为了将follower的log与自己一致。Leader必须找两个日志一致的最新的日志条目,删除该点之后的所有条目,并将该点之后的所有Leader的条目复制给follower(找到一致的点,作为基准,然后在该点之后强制覆盖Leader的内容)
上图演示了所有follower可能出现的状态。方框中的数字就是在哪个term产生的log条目,a-b情况就是follower有遗漏,c-d存在多的未提交条目,e-f两种情况都包含,为什么会出现这种情况呢?以f举例,如果f曾经是Leader在term2的时候,添加了几条内容在log里面,然后在commit这些变动的时候之前就宕机了,然后他迅速的重启了,还变成了term3的Leader,又添加了一些内容到log里面,在term2和term3,committed之前再次宕机,然后就一直宕机错过了后续的term。就是f这种情况。