今天看 redis 哨兵部分的时候看见 哨兵选leader 采用的是 Raft协议,因而就了解了一下Raft协议;redis
a、Raft 协议是借鉴了 Paxos协议,可是思路又与Paxos不同网络
b、主要思想:多数成员赞成/同意就能成为master/leaderspa
与Paxos协议的区别日志
a、Paxos 协议对leader选举没有明确限制,可是必定要保证数据一致性,数据同步很复杂;同步
b、Raft 协议能够有多个leader存在,可是同时被承认的leader只会有一个,同步数据就比Paxos容易;it
Raft协议大体有如下几种状况ast
a、数据广播策略(主正常)原理
a、选leader(发现主异常)配置
b、新leader数据同步(选主后)date
补充:
一、数据都是线性的,即:有自增加的标识符
二、每一个节点leader/follow的数据都分为committed和uncommitted两种数据,committed的数据不能被修改,而uncommitted的数据(老是在committed数据后)能够被删除和修改;
三、每一次选举产生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
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尽量只参加一轮投票;
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(配置票数,哨兵节点数/2+1))成功后,就会进行故障转移,选新的redis-master