Raft使用较为广泛的强一致性、去中心化、高可用的分布式协议,即使在网络、节点故障等情况下,多个节点依然能达到一致性。
其中redis、etcd等都用到了这种算法
在Redis集群中,采取的主从复制结构,当主节点宕机后,哨兵会将其中的一个从节点升级为主节点,而其中选举的过程就是Raft算法。
原理:
- leader:领导者,其负责和客户端通信,接收来自客户端的命令并将其转发给follower
- follower:跟随者,其一丝不苟的执行来自leader的命令
- candidate:候选者,当follower长时间没收到 leader的消息就会向成为候选者,抢夺成为leader的资格。
下面我讲一下以一个例子来讲解一下整个的过程:
假设我们有三个哨兵(sentenal1,sentenal2,sentenal3),一个主节点(redis-master),两个从节点(redis-slave1,redis-slave2)
当主节点出现故障,就会触发重新⼀系列过程.
主观下线:当主节点宕机后,此时主节点和3个哨兵之间的心跳没有了。
这是哨兵认为,主节点出现了严重事故,因此三个哨兵均会把主节点判定为主观下线
客观下线:哨兵sentenal1,sentenal2,sentenal3均会对主节点故障进行投票,当故障票数 > 陪定的法定票数的时候,就将它认为是客观下线
假设一共有3个哨兵节点,S1,S2,S3
- 每个哨兵节点都会给其他哨兵节点发起一个投票请求,
- 此时收到请求的节点会选择是否投还是不投(每个哨兵节点都只有一票)
- 一轮投票结束后,发现得票数数超过节点的一半的时候,自动升级为leader
- leader会负责挑选一个从节点升级为新的主节点,当其他的sentenal发现新的主节点出现的时候,就说明选举结束了
那么挑选的规则是什么呢?
- 比较优先级:优先级高的上位,优先级是slave-priority或者replica-priority
- 比较replication offset,这个反映了从节点有多少数据和主节点一样,replication offset高的上位
- 比较run id,谁的id小,谁上位
哨兵节点不能只有一个吗?
当然不能,我们要知道在redis一般是以集群的方式来部署的,那么就有可能哨兵节点挂了,那么就会影响系统的可用性(这是不能忽视的)
哨兵节点设置为奇数还是偶数
哨兵节点设置为奇数,方便选举leader,得票数容易超过总节点的一半
投票时,如果超过了超时时间导致选取不出leader怎么办?
raft算法其实都有考量,所有节点都会被分配不同的超时时间,因为如果都分配相同的超时时间,导致所有节点同时过期,导致无法选举出leader的情况
如果哨兵节点是偶数,出现了平票怎么办
此时,所有节点都会变为follower状态,重新设置随机的超时时间,重新进行选举