一个关于 Raft 协议的疑问

2020-07-02 08:57:39 +08:00
 phpcyy

如果有 A 、B 、C 、D 、E 一共 5 个节点,A 是 Leader 。 原本的 logIndex 都是 3,如果 A 发送了 4 的日志,B 、C 确认,获得多数 ack,会返回 client 成功。

第一个问题: 这时候如果 Leader 挂掉,B 、C 还没来得及接收下次心跳进入 committed 状态,4 这条日志仍然能保存成功吗?

第二个问题: 如果这时候 A 、B 挂掉,4 这条日志还能确保可以成功保存吗?

最近在看 Raft 相关文章,都没理解上边的这个情况该如何处理,所以求教大家,不胜感激。

我的理解是第一种情况,需要获得多数节点 4 这条日志的状态,B 、C 加上必然存在该消息的 Leader,可以过半,因此可以保存成功。

第二种情况看起来系统已经不能正常工作了,无法确认这条 uncommited 的消息是否需要保存。

4506 次点击
所在节点    程序员
42 条回复
chihiro2014
2020-07-02 09:05:08 +08:00
看 mit 6.824 岂不是更香?里面都有讲解这块的
https://www.bilibili.com/video/av91748150
BBCCBB
2020-07-02 09:08:11 +08:00
第一个问题, 可以保存成功, 因为 D,E 的日志比 B,C 上的旧, 所以下一轮选举 B,C 是不会投给 D,E 的, 下一轮的 leader 只会从 B,C 中选出.

第二个问题, 因为 C 的日志比 D,E 的新, 剩下 C,D,E 3 个节点, 就是说要所有投票投给一个节点才能继续工作, 那肯定也只有所有投票投给 C 才能继续工作, 所以 4 依然是已经保存了的..

我做 6.824 过了好几个月了, 可能有误, 仅供参考, 欢迎指正
luckyrayyy
2020-07-02 09:08:48 +08:00
phpcyy
2020-07-02 09:12:36 +08:00
@BBCCBB

针对第二种情况,如果 A 、B 挂了,C 的 4 可能是 2 种情况,A 、C 上有,A 、B 、C 上有,如果前一种情况那么没达成共识,如果后一种情况达成了共识,C 无法断定是哪一种情况啊。
OSDI
2020-07-02 09:16:53 +08:00
原论文图八说明的情况就是,都不能保证的吧
BBCCBB
2020-07-02 09:21:40 +08:00
@phpcyy 我以为你说的第二种是 4 已经提交到 A,B,C 了呢... 按你说的 A,B,C 都已经提交 4 了呀..

如果 4 已经被 commit 了, 那肯定没问题

如果 4 没被提交, 剩下 C,D,E 节点, 4 被包含在里面也没啥问题, 只是成了脏数据..


> 毕竟 raft, paxos 这种是肯定保证如果多数确认, 并且提交了, 那数据肯定不会丢失的..
kmyzzy
2020-07-02 09:28:54 +08:00
@phpcyy A 、B 挂了只有 C 能成为 Leader,C 会把 4 发给 D 、E,所以只要 C 能在自己的 Term 成功 commit 一个 log,4 就一定能保存。
phpcyy
2020-07-02 09:32:12 +08:00
@BBCCBB

我的意思是 A 提交了 4,B 、C 收到了进入 uncommited 状态,需要在 A 下一次心跳的时候变为 commited,但是 A Commit 后没来得及心跳就挂了,B 、C 处于 uncommited 状态,这时候发生了重新选举。

1. 在这种情况下,如果 A 挂了,B 、C 活着,能否保证 4 这条消息不会丢失。

2. 如果 A 、B 挂了,C 活着,能否保证 4 这条消息不会丢失。

第一种情况下,B 、C 理论上仍然可以就 4 这条消息达成多数。
第二种情况下,C 无法确认 4 这条消息是否达成多数,丢弃和不丢弃无法确定,因为它不知道 B 是否保存过 4 这条消息。
phpcyy
2020-07-02 09:33:53 +08:00
@kmyzzy 是这样的,C 的 4 这条消息是 uncommited 状态,如果它采纳了,那么可能是脏数据;如果不采纳,可能会丢失数据。除非整个集群不工作了等待 A 、B 复活。
lance6716
2020-07-02 09:36:05 +08:00
4 这个日志会在本地持久化的因此不会丢,并且协议保证其他机器的 4 不会有不用的日志 append 成功
phpcyy
2020-07-02 09:38:37 +08:00
@lance6716 4 这个消息会持久化到 A,那其他节点若正常工作,在我描述的情况下 4 会被正常复制到其他节点吗?
OSDI
2020-07-02 09:40:08 +08:00
@OSDI 抱歉,看错了
BBCCBB
2020-07-02 09:43:19 +08:00
@phpcyy
第二种情况, C 不需要确认 4 是否达成多数, 这个是由 A 来判断的, A 判断多数已经提交了, 那就可以返回 4 已经保存成功..

A,B 宕机后, C 日志最新, 会成为 Leader, 所以 4 依然不会丢失.
BBCCBB
2020-07-02 09:44:21 +08:00
@OSDI 哈哈, figure 8 是处理不能主动提交上一个 term 的 log 吧
lllllIIIlll
2020-07-02 10:28:35 +08:00
第二种情况下,C 无法确认 4 这条消息是否达成多数,丢弃和不丢弃无法确定,因为它不知道 B 是否保存过 4 这条消息。
---------------
这应该也是当前 Term 的 Leader 不主动提交上一个 Leader 的原因吧,因为 C 无法根据自己的信息确认上一个 term 的消息是否复制到了大多数节点。
按你说的第二种情况,C 并不知道 log 4 是否已经复制到了大多数节点上,但是由于 C 此时的 log 是 more up-to-date 的,所以一定是 C 当选 leader,然后 C 会与其他 follower 同步日志,并且在成功 commit 一条自己 Term 中的日志后隐式地提交 log 4 。
针对 log 4 的两种情况:
1. A 没有把 log 4 复制到大多数节点 =>那么 C 在同步日志时,相当于代替 A 复制了 log 4 。
2. A 把 log 4 复制到了大多数节点 => 那么 C 同步日志没有问题,相当于代替 A commit 了 log4 。
并不会产生错误。

很久之前看的 raft 了,不保证细节完全正确。
@phpcyy
bilosikia
2020-07-02 10:31:50 +08:00
1. 第一个是能保存成功的,1. leader 选出新的 leader 一定包含最新的 log 2. 前任 leader 的 log 谁着新任 leader 一起提交
2. 半数以上节点可用就行,A,B 挂了,只有 C 节点能当选新 leader
sunznx
2020-07-02 10:44:04 +08:00
如果有 A 、B 、C 、D 、E 一共 5 个节点,A 是 Leader 。 原本的 logIndex 都是 3,如果 A 发送了 4 的日志,B 、C 确认,获得多数 ack,会返回 client 成功。

第一个问题: 这时候如果 Leader 挂掉,B 、C 还没来得及接收下次心跳进入 committed 状态,4 这条日志仍然能保存成功吗?
------------
能成功,因为 A 已经成功返回给 client 了。

第二个问题: 如果这时候 A 、B 挂掉,4 这条日志还能确保可以成功保存吗?
------------
可以,因为 raft 保证日志一旦被提交给客户端,就一定是成功的
phpcyy
2020-07-02 10:47:07 +08:00
@lllllIIIlll

针对 log 4 的两种情况:
1. A 没有把 log 4 复制到大多数节点 =>那么 C 在同步日志时,相当于代替 A 复制了 log 4 。
---------------------------------------------------------

C 代替 A 复制了 log 4 并 commit,即使 A 可能出现未 commit 的情况,对吗?

好像有点明白了,只保证 leader 已 commit 的必定会保存,但是原 leader 未 commit 的消息仍然会由新 leader 广播其他节点保存,但 client 可能收不到响应,不知道是不是这样?
noogler67
2020-07-02 11:24:00 +08:00
第二个问题,raft 会保证选举出来的 leader 带有 4 。选举 leader 的时候会判断 candidate 的 log ( term 更旧则拒绝,相同 term 更短则拒绝),所以只有 c 能当选。
这也是 raft 的核心,一旦 commit,就肯定能保存记录。
misaka19000
2020-07-02 11:36:11 +08:00
想起来当初自己折腾 raft 的时光。。。现在已经全部忘光了

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

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

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

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

© 2021 V2EX