raft 笔记

leader选举

目标 :确保所以log的entry 传送方向是: leader -> follower
策略:选出的leader就包含所有term中已经提交的log entry


目标:选出包含所有term中已经提交的log entry的leader
策略:只向比自己更新的cadidate投票。

更新:
1 最后一条log entry 的term 大的更新。
2 在1 条件下,日志更长的更新。

如何提交之前任期内的log entry

raft 笔记_第1张图片
image.png

如图的时间序列展示了为什么 leader 无法判断老的任期号内的日志是否已经被提交。在 (a) 中,S1 是 leader ,部分地复制了索引位置 2 的日志条目。在 (b) 中,S1 崩溃了,然后 S5 在任期 3 中通过 S3、S4 和自己的选票赢得选举,然后从客户端接收了一条不一样的日志条目放在了索引 2 处。然后到 (c),S5 又崩溃了;S1 重新启动,选举成功,继续复制日志。此时,来自任期 2 的那条日志已经被复制到了集群中的大多数机器上,但是还没有被提交。如果 S1 在 (d) 中又崩溃了,S5 可以重新被选举成功(通过来自 S2,S3 和 S4 的选票),然后覆盖了他们在索引 2 处的日志。但是,在崩溃之前,如果 S1 在自己的任期里复制了日志条目到大多数机器上,如 (e) 中,然后这个条目就会被提交(S5 就不可能选举成功)。 在这种情况下,之前的所有日志也被提交了。

在c状态下 对于 2 号log entry 是否已经做过commit(虽然副本数已经过半),leader能否做出判断?
答案: 不能

因为如果此时如果认为2 号log entry 已经提交,并且将2号应用与状态机,那么接下来的可能的发展方向是什么呢?
d 状态是一种发展方向,此时2号entry完全覆盖掉了,一个被commit(或者应用到状态机) 的entry竟然被覆盖掉了,what? 这能忍吗?显然不行。

如何避免?
我们发现如果朝着 e方向发展,在e的状态下,认为2是提交的完全没有问题(不可能再有任何情况会将2 覆盖掉)。
那么e是什么状态呢?
e 的状态在当前(最新的)任期内commit了一条新的 log entry。
所以:
老任期内的log entry被当前任期内的新(对新 log entry)commit 间接提交。
换句话说: 老任期内的log entry 能不能看做是被提交的还得依赖后面有没有新的log entry commit过。

你可能感兴趣的:(raft 笔记)