前
raft是paxos的简化,同样是有拜占庭问题演化而来。
http://thesecretlivesofdata.com/raft/ raft动画演示
角色介绍
将网络中的服务器看成节点。
leader(主)
所有的写操作都是通过主来控制的。
follower (从)
“从” 接收 “主” 的信息,并丰富自己的日志
candidate (候选人)
候选人阶段,是成为“主”或者“从”。
过程
注:“从”节点没有收到心跳包,或者leader没有收到半数回复,都会根据自身的超时时间进行等待。
注:每一轮选举中,每个节点只能投一票
选举
- 刚开始还是在没有leader的阶段,所有的节点默认为follower,开始进行倒计时
timeout
。(timeout时间为150ms到300ms之间,随机分布) 分歧一
:有一个节点率先结束了timeout,成为了candidate(候选人),然后开始进行发起投票请求,请求别的节点认可成为leader。- 其他还没timeout的节点收到了
投票
请求,则会进行投票,返回给候选人。 - 候选人收到半数以上的其他节点支持的时候,则会成为leader,其他的节点则会成为follower。
- leader会在timeout结束前定时发送心跳包。
分歧二
:分歧一是只有一个节点率先结束,二则是有可能会有多个节点同时结束,然后对除了自己以为的节点发起投票。- 其他节点的票则会根据请求发送给最早的请求,之后的同一轮的投票则会进行拒绝。
- 如果这时
候选人
节点都没有收到半数以上的投票,则会等待timeout的结束,开始下一轮的选举。 - 下一轮的选举还是按照第一步的节奏,开始,直到有leader选举出来。
日志复制
正常环境下(网络没有被分区)
- client发送信息给leader
- leader接收到信息,并保存到log中,并标记状态是未提交。
- 之后发送同样的信息给follower们,followers接收到信息,保存在日志中,并标记 未提交,并返回确认给leader
- leader收到半数的followers的回复后,会将信息进行提交。并返回成功给client
- 再发送信息给followers,让他们对信息进行提交。
网络分区
- client发送给leader,leader标记未提交,再发送给followers。
- 但是follower的回复没有超过半数,则会返回失败给client
- 这时另外分区的节点,由于没有收到leader的心跳包,等待时间超过timeout后,则会进入候选人阶段,候选人则按照选举规则进行选举,选举出新的leader后,则会开始新的一轮日志复制。
- 当网络恢复的时候,一个分区内就产生了2个leader。
这时的两个leader是不同轮的leader,新的leader 轮数是2,旧的leader 轮数是1,所以旧的leader收到了新leader的心跳包会检查轮数,发现自己已经过期,则会成为follower
- 之后会通过同步的方式将新leader中,自己没有保存的日志进行复制同步。