难以理解github
Paxos算法是如何工做的?网络
Paxos算法每一个阶段的意图是什么?app
很难产生直观的感觉。分布式
难以实现并应用于现实中的系统ide
人们在实现Paxos算法时,发现不少实现上的难题,最终开发出和Paxos算法不同的结构。
Raft协议由Diego Ongaro和John Ousterhout(斯坦福大学)共同于2014年设计。
每个服务器存储着一个日志序列。每个服务器按照顺序应用每条日志(或称之为执行指令),并应用到状态机中。
保证了日志序列相同,那么,在应用每条日志(或称之为执行每一个指令)时,每台服务器的状态机状态都是一致的。
保证日志序列相同就是一致性算法的工做。
Raft选举出一个Leader,经过Leader管理日志复制来实现一致性。
Leader从客户端接收日志条目,将日志条目复制到其余服务器上。当确保安全性的时候,告诉其余的服务器应用日志条目到他们的状态机上。
为了可理解性,Raft对经过问题分解,将算法分为了几个独立的部分
Leader选举
日志复制
安全性问题
特性 |
解释 |
---|---|
选举安全原则 |
对于一个给定的任期号,最多只会有一个领导人被选举出来 |
领导人只附加原则 |
领导人绝对不会删除或者覆盖本身的日志,只会增长 |
日志匹配原则 |
若是两个日志在相同的索引位置的日志条目的任期号相同,那么咱们就认为这个日志从头到这个索引位置之间所有彻底相同 |
领导人彻底原则 |
若是某个日志条目在某个任期号中已经被提交,那么这个条目必然出如今更大任期号的全部领导人中 |
状态机安全原则 |
若是一个领导人已经在给定的索引值位置的日志条目应用到状态机中,那么其余任何的服务器在这个索引位置不会提交一个不一样的日志 |
一个Raft集群包含若干个服务器节点,一般是5个,容许整个系统容忍2个节点的失效。
在任什么时候刻,每个服务期节点都处于如下3种状态之一:
Leader:处理全部的客户端请求(若是客户端将请求发给了Follower,Follower会把请求重定向给Leader)
Follower:不会发送任何请求,只会简单地响应来自Leader或Candidate的请求
Candidate:用于选举产生新的领导人
Term——任期
1)每一个任期最多只能有一个领导人Leader
2)有时候任期内可能没有领导人(因选举失败)
3)每台机器上维持着当前的任期号。
会在每次RPC通讯时会将本身的任期号进行传递(可用于识别过期的信息)
若是RPC收到任期号大的值,变为follower。
若是RPC收到过时的任期号,返回错误信息。
1)每一个机器只能投一次票(含投给本身)
2)得到多数选票的成为leader
问题:
若是选举过程当中,一直没有一个Candidate得到大多数选票,将一直进行重复选举。
如何保证会有一个Candidate会获取到大多数选票成为Leader?
Raft的解决方法:随机超时时间,保证只有一个follewer超时,变成Candidate,并(在其余follower超时前)发送投票请求,获得大多数的选票,从而成为leader。
客户端发送命令给Leader。
Leader把日志条目加到本身的日志里。
Leader发送AppendEntries RPC请求给全部的follower。
AppendEntries RPC里包含着prevLogIndex,prevLogTerm。
Follower接收到后,会检查相应的日志条目是否匹配上
1)若是匹配上了(Example#1),将收到的日志条目添加到本身的日志里。
(根据【日志匹配原则】,表示follower和leader的prevLogIndex之前的全部日志条目是安全相同的)
2)若是没有匹配上(Example#2),follower将拒绝这次请求,Leader将index调小,不断进行重试,直到匹配上。
(Example#3)follower会将后面的日志条目所有删除,再将leader的日志条目添加上。
(日志提交:指将日志条目应用到状态机中)
一旦新的日志条目变成【已经复制到大多数follower机器上】的了。
(PS:关于上面所讲的“大多数follower机器”个数?
问题:能够这么理解吗?
知足【“大多数follower机器”个数 + leader > 集群中机器个数的一半】就能够。
好比,集群中机器个数为5,“大多数follower机器”个数为2就能够了。
答案:
不能够,由于若是leader宕机不重启,没法保证仍旧为大多数。
)
Leader在状态机里提交本身日志条目,而后返回结果给客户端
Leader下次发送AppendEntries RPC时,告知follower已经提交的日志条目信息(lastIndex)
foller收到RPC后,提交到本身的状态机里
在Raft运行过程当中,可能的各个机器日志条目状态以下。
问题:
领导人S1宕机了,从新进行选举,是每台机器均可以被选举成为新leader吗?
若是S4被选举成term 4的leader,会发生什么问题?
答案:
当S4发送AppendEntries RPC请求给全部的follower时,
在进行日志一致性检查时,会将follower已经提交到状态机中的日志条目给删除掉!!从而违反了状态机安全原则。
如何保证选举出的新leader包含全部已提交的日志条目?
选举规则的限制:Candidate发送的RequestVote RPC中含有lastIndex,lastTerm。
当机器收到后,若是Candidate的日志不如本身的新,将拒绝投票给它。
日志的新旧的比较:经过比较两份日志中最后一条日志条目的索引值和任期号定义谁的日志比较新。
若是两份日志最后的条目的任期号不一样,那么任期号大的日志更加新。
若是两份日志最后的条目任期号相同,那么日志比较长的那个就更加新。
S1:选票(S1,S2,S3,S4,S5)可得到多数选票
S2:选票(S2,S4)
S3:选票(S1,S2,S3,S4,S5)可得到多数选票
S4:选票(S4)
S5:选票(S2,S4,S5)可得到多数选票
所以,S1, S3, S5可被选举为新的leader,S2,S4则不行。
思考:为什么经过这种方式能够保证新选举的leader必定拥有已commit的日志条目?
答案:
leader在当日志条目【已经复制到大多数follower机器上】时,才会提交日志条目。
假设已经含有已提交日志条目的机器(可能含上一次的leader)组成的集合为Set。
根据以上选举规则的限制,可知新leader必定在Set中。
[1] https://raft.github.io/raft.pdf Raft论文原文
[2] https://github.com/maemual/raft-zh_cn/blob/master/raft-zh_cn.md Raft论文翻译
[4] https://raft.github.io/ Raft官网
[5] http://thesecretlivesofdata.com/raft/ Raft算法可视化
[6] https://raft.github.io/slides/uiuc2016.pdf
https://www.youtube.com/watch?v=vYp4LYbnnW8&feature=youtu.be
Raft论文做者PPT讲稿及视频