xnnyygn / xraft

xnnyygn's raft implementation
MIT License
229 stars 108 forks source link

向您请教我目前遇见的问题 #7

Open renxinlin opened 4 years ago

renxinlin commented 4 years ago

以A B C 为集群
1 生成log-0 log-10 log-15 三个日志,此时log-15已经生成快照
2 这时候宕机A,B,C 并且删除B的日志 3 此时启动A,C A,C节点开始选举 term增加【假设为9】,但是快照的term还没有增加【假设为7】 4 此时B重新启动 开始installing快照 ;快照安装成功后,开始追加日志 问题: 追加日志的时候,取消息的term和本地快照的term比较 但是本地的来源于刚刚的installing的term 也就是7,而追加日志的term来源于日志最新的term[9]

此时一直报错 AbstractLog - previous log index matches snapshot's last included index, but term not (expected 40, actual 36)

必须等待客户端操作从而推进日志代生成;直到跳过当前日志生成代到下一个后,B更新新的日志才能恢复; 假如shouldGenerateSnapshot过大 那么在下一个日志代不会快速生成 B节点无法更新快照只能基于当前快照提供服务 如果 kvstore-set x 12 此时在A可以获取,但B节点无法获取

此问题的原因在于节点非优雅宕机,日志term更新后,快照term尚未更新;请问能否加入相关机制优化【???】

xnnyygn commented 4 years ago

你好,从你的描述来看,是某个节点生成了快照,但是其他节点没有生成的情况么?如果可以的话,是否可以给出出错时,各个节点的日志?

另外,我不确定您是怎么删除节点B的日志的。节点的状态除了日志之外,还有一个NodeStore。这是一个二进制文件,里面包含了最近的term等信息。如果这个文件没有被删除,有可能导致接下来节点的状态不正常。

renxinlin commented 4 years ago

复现: 1 配置集群为A,B,C三台节点 2只启动A,B 备注:[此时集群开始正常工作] 3 启动客户端 执行kvstore-set命令 ,A,B此时会生成快照 【问题开始】 4 停止A,B节点 5 重新启动A,B节点 ,此时A,B要进行选举 term开始增加
问题描述:此时日志文件的index和term都向前推进 但快照文件的term已经为最新term-1 6 此时启动节点C C收到心跳后由于index落后太多转到快照复制,此时获取的term为最新的term-1 快照复制完毕后 开始日志复制 【问题产生】 checkIfPreviousLogMatches if (prevLogIndex == lastIncludedIndex) { int lastIncludedTerm = snapshot.getLastIncludedTerm(); if (prevLogTerm != lastIncludedTerm) { logger.debug("previous log index matches snapshot's last included index, " + "but term not (expected {}, actual {})", lastIncludedTerm, prevLogTerm); return false; } return true; } 此时term始终比对不上 直到下一个installing快照过来,该节点才恢复正常 log.zip