安全性
安全性是指Raft需要保证每个状态机需要以相同的顺序执行相同的命令。我们前面所说的领导者选举和日志复制的机制并不足以保证这个要求。
选举约束
前面所讲的选举机制,还存在一个问题。例如,当一个跟随者不可用时,领导者提交了几个日志(注:只要有大多数机器存活,raft算法就能正常运转并且保证数据一致性)。然后,这个跟随者从故障中恢复并且被选举为领导者。此时,领导者的日志跟其他跟随者的日志存在冲突。根据前面的日志复制章节,对于这种情况,领导者会强制跟随者复制自己的日志来解决不一致的问题。但是,现在这样做会使得不同服务器的状态机没有以相同的顺序执行相同命令。
所以,对于这种情况,简单的做法就是:不允许这样的跟随者或者候选者称为领导者。
也就是说,新的领导者必须包含所有已提交的日志。
也就是说,一个候选者必须包含所有已提交的日志,才能赢得选举。
也就是说,RequestVote消息中应该包含候选人的日志信息。如果投票的人发现它的日志比候选人的日志新,它可以拒绝投票。
那怎么判断两个日志哪个是最新的呢?通过日志中最后一个日志项的任期和索引来比较。比较过程为:
- 如果任期不同,那么拥有更大编号任期的日志是最新的。
- 如果任期相同,那么拥有更大索引的日志是最新的。
基于这个问题,我们对选举过程提出了一个约束:
领导者的完整性:
如果一个日志项在某个任期已经被提交了,那么这个条目一定会出现在更大编号任期内的领导者的日志中。
提交先前任期的日志项
raft中,新的领导者不会提交先前任期的日志(来自先前领导者)。一旦一个来自当前任期的日志项被提交后,(在这个日志项)之前的所有日志项都会被间接提交,因为日志复制章节的日志匹配特性。
相比其他一致性算法,raft算法保持了先前任期日志项的任期,
- 由于日志项在不同时间、不同日志之间保持相同任期,使得我们更容易推理日志项,使得系统行为可预测。
- 不需要发送多余的日志项来重新编号先前任期的日志项,减少了网络通信。
安全性证明
- 证明领导者完整性。
- 由领导者完整性证明状态机安全性。
- 状态机安全性 + 按日志索引应用日志 --> 所有状态机以相同的顺序执行相同的命令。
领导者完整性特性
领导者完整性特性:如果某个任期内的某个日志项已提交,那么后面任期的领导者的日志中都会包含这个日志项。
假设 leaderT 在它的任期T内提交了一个日志项,但是这个日志项没有被一些未来任期的领导者存储。假设大于任期 T 的所有任期中,存在一个最小任期 U,它的领导者 leaderU 没有存储这个日志项。
- 在选举 leaderU 的时候,它的日志中没有这个已提交的日志项。因为领导者不能删除覆盖或删除自己的日志项。
- leaderT 把这个日志项复制给了集群中的大多数服务器,而 leaderU 接收到了集群中大多数服务器投的赞同票。因此,至少有一个服务器即接受了 leaderT 的日志项,也为 leaderU 投了票。这个投票者是达到矛盾的关键点。
- 这个投票者一定是先接受了 leaderT 的日志项,再为 leaderU 投了票。如果不是这样的话,这个投票者会拒绝存储 leaderT 的日志项,因为它的当前任期比 leaderT 的当前任期大。相比步骤2,步骤3强调了投票者这两个操作的顺序性
- 这个投票者为 leaderU 投票时,它的日志中仍然存储了 leaderT 提交的日志项。因为每个在 [T,U) 的领导者不会移除日志项,跟随者只会移除它们跟领导者冲突的日志。相比步骤3,步骤4强调了投票者投票时的日志内容
- 投票者把它的票投给了 leaderU,说明 leaderT 的日志至少是跟投票者是一样新的,也就是说,投票者的日志内容要么跟 leaderT 的日志内容完全一样,要么是 leaderT 日志内容的子集。这个导致了两个矛盾点中的一个。
- 首先,如果投票者和 leaderU 的最后一个日志项的任期相同(加上步骤5这个大前提),那么 leaderU 的日志至少跟投票者的日志一样长,所以 leaderU 的日志包含了投票者日志中的每一项。这是个矛盾,因为我们已经假设了leaderU 没有存储这个日志项。
- 否则,leaderU 的最后一个日志项的任期大于投票者的。这个日志项的任期是大于 T 的,因为投票者的最后一个日志项的任期至少是 T(从步骤2知道,它包含了任期T内已提交的日志项)。创建 leaderU 最后一个日志项的领导者一定已经包含了任期 T 内已提交的日志项(从假设得知)。然后,根据日志匹配特性,leaderU 的日志一定也包含了这个已提交的日志项,跟假设冲突了。
- 因此,所有任期大于 T 的领导者一定包含了任期 T 提交的所有日志项。
- 日志匹配特性保证了未来的领导者也将包含那些间接提交的日志项,即大多数服务器存储了这个日志条目,还没有应用到状态机。那么,新的领导者一定是从这些服务器产生,并且他们提交自己任期的日志条目时,也会根据日志匹配特性,一并提交先前任期的日志条目。
状态机安全性
状态机安全性:如果一个服务器已经把某个给定索引的日志项应用到状态机了,那么没有其它服务器会为相同的索引应用不同的日志项。
如果一个服务器应用了某个给定索引的日志项,那么这个日志项一定是已经被提交了的,并且在这个日志项之前,包括这个日志项,服务器的日志和领导者的日志是保持一致的。
根据日志完整性特性,后面任期的领导者也保存了相同的日志项,所以,在后面任期应用这个索引的服务器也会应用同样的值。
不是很理解