Closed hanzhihua closed 1 year ago
看代码reset是发生在做完快照的时检查快照index的term跟日志进行比较不一致时做的动作。 如果是本地做快照,如果是第一次load的化,是不是日志跟快照不匹配,简单的删除存在日志是不是合理呢。如果后续做快照,理论上不应该出现这种情况,出现了应该是bug。 如果是远程copy 快照过来,也不应该出现这种情况,正常情况应该是term=0 另外reset这个操作不确定是不是合理,是不是直接交给上层处理,对raft协议了解不多,请指教,多谢
// term = 本地的term,来自本地快照或者log
if (term == 0) {
// 。。。
} else if (term == meta.getLastIncludedTerm()) {
// 本地term=snapshot的term,说明本节点没有落后太多,甚至可能在此之前本节点是leader,拥有一些不该存在的log,因此可能需要truncate
} else {
// 本地term!=snapshot的term,可能本地term大于,也可能小于,都是允许的情况。
// 如果大于(因为prevote的存在,这种情况应该不存在),在此之前本节点是leader,提出一些日志,未达成共识。
// 如果小于,在此之前本节点也可能是leader,提出一些日志后,宕机了很久,恢复过来后,它应该以当前leader为准。
if (!reset(meta.getLastIncludedIndex() + 1)) {
}
}
理解,reset方法只出现在从leader copy 快照过来,而且跟本地日志有冲突,如你举的场景。 我有一个不成熟建议,其实在jraft中有很多这样的方法,只会出现在特点的场景,如这个reset,还有checkAndResolveConflict方法中,firstLogEntry.getId().getIndex() == 0只出现leader中,不等于0是follower中,是不是可以加上一个Requires限制,可以快速发现问题。
因为我早期使用jraft时候,就出现了firstLogEntry.getId().getIndex() != 0 出现leader中,主要原因是raft 线程池满了出错了(线程主要用在rpc中同步中)
Your question
问一下logmanager reset主要是发生在什么场景,不太理解这个
Environment
java -version
): 1.8uname -a
):