Raft 协议
今天看 redis 哨兵部分的时候看见 哨兵选leader 采用的是 Raft协议,于是就了解了一下Raft协议;
一、简介
a、Raft 协议是借鉴了 Paxos协议,但是思路又与Paxos不一样
b、主要思想:多数成员同意/赞成就能成为master/leader
与Paxos协议的区别
a、Paxos 协议对leader选举没有明确限制,但是一定要保证数据一致性,数据同步很复杂;
b、Raft 协议可以有多个leader存在,但是同时被认可的leader只会有一个,同步数据就比Paxos容易;
二、原理
Raft协议大致有以下几种情况
a、数据广播策略(主正常)
a、选leader(发现主异常)
b、新leader数据同步(选主后)
补充:
1、数据都是线性的,即:有自增长的标识符
2、每个节点leader/follow的数据都分为committed和uncommitted两种数据,committed的数据不能被修改,而uncommitted的数据(总是在committed数据后)可以被删除和修改;
3、每一次选举产生leader后会有一个记录号Term,自增长
三、数据广播策略
a、当前leader收到客户端数据,会将数据记录下来,但是是uncommitted状态
b、当前leader就会广播最新的数据,并带上自己的Term
c、follow节点就会比对当前leader的Term,如果比自己记录的当前leader小就丢弃该数据(保证同一时间只有一个leader能同步数据)
d、当超过半数的follow节点认为数据有效/可提交,则leader提交数据,记录下最新的commit-index,并将commit-index广播给follow节点
e、follow节点提交数据并更新各自的commit-index
四、leader选举
a、所有的follow节点都能成为candidate(有资格成为leader)
b、当一个candidate发现leader网络有问题时,candidate就会发起选主(选自己)投票
c、各个follow就会比对与candidate数据的长度(不是commit-index),只有超过半数follow认为candidate日志长度要大于等于自己的日志长度,candidate才能成为leader
问题:可能各个follow都会发起选leader投票,导致多轮投票,系统很长时间不能选leader成功
解决:
a、每一轮投票时间长度设置成随机,保证尽可能在同一时间只会有一个candidate在发起投票;
b、各个follow的投票时间也时随机的,保证同一时间,同一个follow尽可能只参加一轮投票;
五、新leader同步数据
a、新leader会去询问所有follow的数据最大长度(不是commit-index)
b、将最长的数据同步过来
c、带上自己当选leader的Term并广播数据同步,参考第三段
结束语:
哨兵的选主实现
a、每个哨兵每秒去轮询各个节点的状态,当发现redis-master挂掉后,发现redis-mster挂掉的哨兵就会认为该redis-master主观下线;
b、将每10s一次的info同步信息策略提升为1s一次的
c、询问其他哨兵当前redis-master是否已经下线
d、超过半数的哨兵认为当前redis-master已经下线,那么就认为该redis-master客观下线
e、客观下线后,该哨兵就会发起选主(选哨兵leader)投票,这通过epoch来表示Term,同一个epoch中,一个哨兵只能投一次票
f、哨兵选主(投票超过max(
))成功后,就会进行故障转移,选新的redis-master