Closed weingithub closed 2 years ago
即使 done 的 entries 是空的,但是还是会将其加入 _disk_queue https://github.com/baidu/braft/blob/575aacaba7e7fa78016224852b5611b3eeeecece/src/braft/log_manager.cpp#L444 又因为_disk_queue 是串行化执行,只有当前面的 entries 落盘后才会返回。
哦哦。如果是这样的话,那的确不会有问题。谢谢
那我想问下,如果我当前这边,把logstorage的append_entries改成异步了。所以log_manager这边有了乱序的情况。那么有哪些问题需要我这边额外关注的?
那我想问下,如果我当前这边,把logstorage的append_entries改成异步了。所以log_manager这边有了乱序的情况。那么有哪些问题需要我这边额外关注的?
append entry 的接口需要变化,完全异步化,解耦 io 的部分和其中计算逻辑,以让 io 的部分能够 dispatch 给 spdk、io uring 等更好的引擎来处理。log 的实现,可以考虑物理 log 基础上可以叠加一层逻辑 log,例如,a b 两个日志并行落盘之后,在逻辑上如果 b 依赖 a,即使 b 先落盘,对外围也是不可见的。 有了这样的 log 实现,pipiline replication、线程模型这些就能进一步改进。
总之,这里有许多工作要做,我们后面也会考虑这些。
那我想问下,如果我当前这边,把logstorage的append_entries改成异步了。所以log_manager这边有了乱序的情况。那么有哪些问题需要我这边额外关注的?
append entry 的接口需要变化,完全异步化,解耦 io 的部分和其中计算逻辑,以让 io 的部分能够 dispatch 给 spdk、io uring 等更好的引擎来处理。log 的实现,可以考虑物理 log 基础上可以叠加一层逻辑 log,例如,a b 两个日志并行落盘之后,在逻辑上如果 b 依赖 a,即使 b 先落盘,对外围也是不可见的。 有了这样的 log 实现,pipiline replication、线程模型这些就能进一步改进。
总之,这里有许多工作要做,我们后面也会考虑这些。
好的,感谢各位的耐心回答。
假设组有A,B,C三个成员,A是leader。构造A,B,C节点持久化故障。即数据无法持久化。一直卡住的状态。 假设此时有index 2,3,4数据。首先,A中,由于无法持久化,所以A本地没有写入成功。 A向B发送数据,此时等到B中entry集合(2,3,4)写入log_manager中的_logs_in_memory,但是卡在底层存储的时候,构造B节点的网络故障,此时A的append_entries请求会失败,之后恢复B节点的网络故障。此时A会将entry集合(2,3,4)重新发送给B,此时由于B中_logs_in_memory已经有了这些entry数据,因此done中的entries会为空,因此会向leader返回本次append_entries成功(LogManager::check_and_resolve_conflict)。A节点会得到B的entry集合(2,3,4)插入成功的结果
C节点同理,构造相同的故障和恢复过程。此时A中也会得到C的entry集合(2,3,4)写入成功的结果。
由于B,C都写入成功,因此entry集合(2,3,4)的数据会被应用到状态机中。 但是此时的entry集合(2,3,4)在ABC节点中都没有持久化成功。此时如果重启A,B,C节点,就会出现数据丢失问题。集群也不可用。 @PFZheng