Raft的特性
Raft 在任何时候都保证以上的各个特性。如何保证特性的
-
选举安全特性
随机的选举超时机制,选举成功后发送心跳包告知他人。
存在的问题:splite vote,通过随机的选举超时机制,进行多轮的超时选举 -
领导人只附加原则、日志匹配原则
领导人处理不一致是通过强制跟随者直接复制自己的日志来解决了。
在发送附加日志 RPC 的时候,领导人会把新的日志条目紧接着之前的条目的索引位置和任期号包含在里面。如果跟随者在它的日志中找不到包含相同索引位置和任期号的条目,那么他就会拒绝接收新的日志条目。
存在的问题:领导人崩溃的情况下,出现的不一致情况
解决:Raft通过附加日志的一致性检查,领导者维护了一个nextIndex数组(发送给某个节点的下一个索引),领导者崩溃恢复,重新初始化nextIndex数组(自己的最后一条日志的index加1),。在被跟随者拒绝之后,领导人就会减小 nextIndex 值并进行重试。最终 nextIndex 会在某个位置使得领导人和跟随者的日志达成一致。通过任期号和索引检查出最开始冲突的地方,这时就会把跟随者冲突的日志条目全部删除并且加上领导人的日志,一旦附加日志 RPC 成功,那么跟随者的日志就会和领导人保持一致,并且在接下来的任期里一直继续保持。 - 领导人完全特性
是选举限制+推迟提交机制保证的
状态机安全特性
最后来讲下这个安全特性的保证
如果某个日志条目在某个任期号中已经被提交,那么这个条目必然出现在更大任期号的所有领导人中
证明
如果 S1 (任期 T 的领导者)提交了一条新的日志在它的任期里,然后 S5 在之后的任期 U 里被选举为领导人,然后至少会有一个机器,如 S3,既拥有来自 S1 的日志,也给 S5 投票了。文中是通过反证法先证明了领导人完全特性,然后证明安全性。
假设
我们假设领导人完全性特性是不存在的,然后我们推出矛盾来。假设任期 T 的领导人(领导人 T)在任期内提交了一条日志条目,但是这条日志条目没有被存储到未来某个任期的领导人的日志中。设大于 T 的最小任期 U 的领导人 U 没有这条日志条目。
反证领导人完全特性
- 由于假设,领导人完全性特性不存在的。term U的领导人S5没有term U的日志条目,收到了来自至少一个拥有term T的日志条目的一T票(图中的S3)
- 根据另外一个假设,大于 T 的最小任期 U 的领导人 U 没有这条日志条目。也就是说再[T...U)之间的领导人都是存在term T的该日志的,U是没有此日志的。
- 投票者把自己选票投给领导人 U 时,领导人 U 的日志必须和投票者自己一样新。这就导致了两者矛盾。
- 如果voter和U的最后的term相同,那么leader U则至少在最后的term的日志和voter的一样长,即包含了leader T提交的log entry;
- 如果voter和U的最后的term不相同,那么U的必定大于voter的,则leader U必须包含term T的所有日志,因为U > T;(日志匹配原则)
- 因此,假设不成立,不可能存在term U,使得term U中的leader不包含之前leader已经提交过的log entry。
安全性证明
现在我们来考虑在任何一个服务器应用一个指定索引位置的日志的最小任期;领导人完全特性保证拥有更高任期号的领导人会存储相同的日志条目,所以之后的任期里应用某个索引位置的日志条目也会是相同的值。因此,状态机安全特性是成立的。
最后,Raft 要求服务器按照日志中索引位置顺序应用日志条目。和状态机安全特性结合起来看,这就意味着所有的服务器会应用相同的日志序列集到自己的状态机中,并且是按照相同的顺序。
网友评论