append log和发送日志的顺序

请教下研发大佬
在2017.3.17日的博客文章Raft 的优化 描述 leader先并行将raftlog发送给fowller然后自己在appendlog。 2019.4.24的tikv源码解析文章里‘raft-rs 日志复制过程分析’ 又说的是 leader append raft log之后再广播发送raft日志。 2个说前后不太一致,且2个文章相差2年,最初的方案是什么样?现在的方案是什么样的? 如果有变化的话是从哪个版本开始的?
谢谢!
https://pingcap.com/zh/blog/optimizing-raft-in-tikv TiKV 功能介绍 - Raft 的优化

https://pingcap.com/zh/blog/tikv-source-code-reading-6 iKV 源码解析系列文章(六)raft-rs 日志复制过程分析

2 个赞

:+1: 坐等大佬回复

1 个赞

大佬们帮解答下

帮助两位大佬确认了一下,这两个博客的表述都是对的,apply log 和append log 的逻辑如下:
写入请求 -> leader 写入内存,更新状态机 ,并行执行 apply 和 append
-> apply log 将raft log 广播到 follower peer
-> append log 将 raft log 落盘到 leader

1 个赞

“追加到自己的 raft log" 以及 “调用 bcast_append” 是在 raft-rs 内的串行内存操作,这两个内存操作之后才会进行 “leader append log” & “发 log 给 follower”, 而这两个 io 操作是分别在不同线程内并行进行的

感谢! 还请问下 “调用 bcast_append” 是由这个函数再去调用发送log的线程吗? 发送 给follower的log是从leader的内存中取出的吧?画了个图不知道流程是不是正确

这个图基本正确,不过 bcast_append 不会直接调用发 log 的线程,bcast_append 只是生成 MsgAppend 消息,等到后面调用 RawNode::ready 的时候才会返回这些消息(放在 Ready 里)然后 leader 会把这些消息发到另一个线程(由这个线程做具体的网络 io)然后 append log

请老师帮忙明确几个疑问,目前这块没太理解:
问题一:
1.bcast_append 生成 MsgAppend信息,此时将log直接写到follower的节点中,直接append,同时leader也进行append,
2.还是说此时leader将log直接写到follower的节点中的内存中,等待leader节点append之后,发送消息确认之后,follower节点才进行append

问题二:
如果问题一的结果是情况1,那么leader节点在append过程中宕机了的话,假如有三个节点,另外两个append成功了,此时是切换leader,还是事务报错

问题一的结果是情况1,leader 宕机了另外两个 follower 会自动选出新的 leader ,而事务的客户端也就是 tidb 因为旧 leader 宕机了一直没回应就会进行重试把请求发到新 leader , 新 leader 处理事务写请求前需要先把旧 leader propose 的日志 commit 并且 apply 了再进行读操作检查事务冲突(如 lock_cf)然后再对重试的事务写请求进一步处理

1 个赞

明白了,非常感谢:+1::+1::+1:

感谢!

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。