问题描述
假设您有 3 个服务器 S1
、S2
和 S3
。 S1
(领导者),将日志复制到 S2
和 S3
,然后将日志响应应用到客户端并崩溃。所以我们有
S1 1
S2 1
S3 1
现在当 S2
成为领导者时(通过 S3
的投票)它将如何应用日志?根据 Raft 论文
If there exists an N such that N > commitIndex,a majority
of matchIndex[i] ≥ N,and log[N].term == currentTerm:
set commitIndex = N.
在上述情况下,S2
(commitIndex
= 0) 的项为 2,而日志的项始终为 1;因此,最后一个条件将不满足?我错过了什么吗?
解决方法
每个节点都有一个事件日志,其中包含两个核心指针:已提交的事件和未提交的事件。该协议的重点是在整个系统中复制两个这些指针。
| 0 1 2 3 | 4 5 6 7 8 9 |
^ ^
Committed Uncommitted
Follower 从Leader 收到的每条复制消息都会更新这两个指针。该消息具有要附加到日志的事件(更新 uncommitted
指针)。它还有一个索引来更新 committed
指针。
当 Follower 收到此消息并更新其 committed
指针时,它会应用所有刚刚从 未提交 移动到 已提交 的事件em>.
发送给 Followers 的 committed
指针是 Leader 在其日志中的副本。当Leader从Follower收到法定人数时更新它的committed
指针,并应用所有从未提交移动到已提交的事件>.
一个新选举的领导者首先需要确保其日志的版本被复制到粉丝,并且随着新的领导者从粉丝收到Quorum,它会更新其committed
指针,将该指针复制回 Followers,并应用上述事件。