raft 中 log replication 的可能造成 leader 丢失已经 committed 的 log 问题

2019-02-16 15:41:27 +08:00
 WithSalt

问题一:

问题二:

2326 次点击
所在节点    云计算
5 条回复
Wisho
2019-02-16 16:58:16 +08:00
不是很懂你的问题二。
论文里这个原图的意思应该是:
(a)时刻,S1 当选,term 号为 2,然后接到客户端的请求,在本地写入(term=2, index=2)的 entry,然后开始 replicate,replicate 到 S2 上,结果意外发生,S1 宕机。
(b)时刻,S1 宕机一段时间后,S5 的 timeout 结束,恰好能参选,发现自己的 latest entry 是(term=1, index=1),还是和大部分人( S3, S4, S5 自己)的 latest entry 保持一致,所以 S5 能够成功当选 leader,term 号为 3。然后马上接到客户端的请求,在本地写入了(term=3, index=2)的 entry,然而 S5 的命运更悲催,还没来得及给兄弟们 replicate,自己就宕机了。
(c)时刻,S5 宕机一段时间后,S1 的 timeout 正好最先结束,决定参选,发现自己的 latest entry 是(term=2, index=2),S2、S3 和 S1 自己都愿意投给 S1,S1 又顺利当选,term 号为 4。此时刚把之前还未完成 replication 的(term=2, index=2)的 entry 分发给 S3,又收到了客户端的请求,请求写入(term=4, index=3)的 entry 到本地。

所以你是指,在(c)时刻,作为 term=4 的 leader,S1 当选后 N 久都收不到客户端的请求写入(term=4, index=3)的 entry,所以有充足的时间把(term=2, index=2)的 entry 分发到所有兄弟上,且 commit 吗?

但是 raft 里的约定就是,term=X 的 leader 是不能直接 commit term < X 的任何记录的,只能在 commit term=X 的记录时把历史上分发成功但是没有 commit 的“顺手” commit 了。
Wisho
2019-02-16 17:14:37 +08:00
接上条回复。

正因为 raft 的这个约定,所以在(c)时刻,即使 S1 这个 term=4 的 leader 把(term=2, index=2)的 entry 成功分发到 S1、S2、S3、S4 上(超过半数),它也不能 commit。不能 commit 就意味着不能回复客户端:“您好,您的操作已生效”,那客户端的“期望”就不会是“哦,存储系统已经帮我存好了,我可以放心了”。

如果在成功分发到 S1、S2、S3、S4 上后(注意是分发成功,但未 commit,未能回复客户端),马上 S1 宕机了。又是那么巧,又是 S5 上线参选,S5 发现“咦? S2、S3、S4 上的 latest entry 都只是(term=2, index=2)而已,我自己最新的是(term=3, index=2),比它们的都新”,所以 S5 能得到大家的投票,S5 当选,term 号为 5。S5 当选后,第一件事就是统一兄弟们的 log entries,一把梭就把(term=3, index=2)分发给大家,直接 overwrite 掉兄弟上的历史记录。

但是这个 overwrite 没关系呀!很正常!为啥没关系,很正常?记得上面我强调的那个“分发成功,但未 commit,未能回复客户端”吗?只要没能 commit 成功,没能回复客户端成功,客户端会认为系统没有给我完成“存储”或者没有给我完成“某种数据操作”,所以客户端也许会超时重试、也许会放弃(取决于具体的业务逻辑)。

但如果你 commit 了(term=2, index=2)的 entry,告诉客户端“放心,成功持久化了”,结果之后被 S5 的(term=3, index=2)给 overwrite 了的话,这会是你的系统的严重失误!分明之前告诉客户端放心没问题存好了,但是之后又“出尔反尔”,把别人的数据给 overwrite 直接搞丢了,就是严重失误。

所以,一切的前提就是 raft 的这个约定,一个非常重要的约定:term=X 的 leader 不能直接 commit term < X 的任何记录,可以分发但不能 commit,直到要 commit term=X 的记录时才能“顺手” commit 历史记录。
Wisho
2019-02-16 17:14:52 +08:00
希望我讲清楚了吧😂
WithSalt
2019-02-16 17:58:32 +08:00
@Wisho (刚来 w2ex,感谢回复者的铜板咋发不出去呢,一刷新就变成原来的状态了)。明白了,一直没有搞清楚这幅图的原因,在于我没有意识到 term 的变化与 leader 的对应关系,每一个 term 都应该只有一个 functional 的 leader。感谢!
Wisho
2019-02-17 04:29:54 +08:00
@WithSalt 客气,我当时也是琢磨了很久,这过程其实最适合用 gif 来解释,而不是静态的(a) ~ (d)的时刻图。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/535625

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX