详解redis sentinel(哨兵模式)的原理和机制

三个定时任务

sentinel在内部有3个定时任务

1.每10秒每个sentinel会对master和slave执行info命令

这个任务达到两个目的:

1.发现slave节点

2.确认主从关系

2.每2秒每个sentinel通过master节点的channel交换信息(pub/sub)

master节点上有一个发布订阅的频道(__sentinel__:hello)。

sentinel节点通过__sentinel__:hello频道进行信息交换(对节点的"看法"和自身的信息),达成共识。

3.每1秒每个sentinel对其他sentinel和redis节点执行ping操作(相互监控)

这个其实是一个心跳检测,是失败判定的依据。

主观下线和客观下线

在redis-sentinel的conf文件里有这么两个配置:

1.sentinel monitor <masterName> <ip> <port> <quorum>

四个参数含义:

masterName这个是对某个master+slave组合的一个区分标识(一套sentinel是可以监听多套master+slave这样的组合的)。

ip 和 port 就是master节点的 ip 和 端口号。

quorum这个参数是进行客观下线的一个依据,意思是至少有 quorum 个sentinel主观的认为这个master有故障,才会对这个master进行下线以及故障转移。因为有的时候,某个sentinel节点可能因为自身网络原因,导致无法连接master,而此时master并没有出现故障,所以这就需要多个sentinel都一致认为该master有问题,才可以进行下一步操作,这就保证了公平性和高可用。

2.sentinel down-after-milliseconds <masterName> <timeout> 

这个配置其实就是进行主观下线的一个依据,masterName这个参数不用说了,timeout是一个毫秒值,表示:如果这台sentinel超过timeout这个时间都无法连通master包括slave(slave不需要客观下线,因为不需要故障转移)的话,就会主观认为该master已经下线(实际下线需要客观下线的判断通过才会下线)

那么,多个sentinel之间是如何达到共识的呢?

这就是依赖于前面说的第二个定时任务,某个sentinel先将master节点进行一个主观下线,然后会将这个判定通过sentinel is-master-down-by-addr这个命令问对应的节点是否也同样认为该addr的master节点要做客观下线。最后当达成这一共识的sentinel个数达到前面说的quorum设置的这个值时,就会对该master节点下线进行故障转移。quorum的值一般设置为sentinel个数的二分之一加1,例如3个sentinel就设置2

领导者选举

为什么要选领导者?因为只能有一个sentinel节点去完成故障转移

sentinel is-master-down-by-addr这个命令有两个作用,一是确认下线判定,二是进行领导者选举。

选举过程:

1.每个做主观下线的sentinel节点向其他sentinel节点发送上面那条命令,要求将它设置为领导者。

2.收到命令的sentinel节点如果还没有同意过其他的sentinel发送的命令(还未投过票),那么就会同意,否则拒绝。

3.如果该sentinel节点发现自己的票数已经过半且达到了quorum的值,就会成为领导者

4.如果这个过程出现多个sentinel成为领导者,则会等待一段时间重新选举。

故障转移

所谓故障转移就是当master宕机,选一个合适的slave来晋升为master的操作,redis-sentinel会自动完成这个,不需要我们手动来实现。

那么,如何选择一个合适的slave呢?顺序如下:

1.选择slave-priority(slave节点优先级配置)最高的slave节点,(默认都是一样的)例如:如果我们有两台slave在两台机器上,一台配置较高,我们希望当master挂掉优先选配置高的,就可以配置该值为slave中最高的。如果存在最高则返回,不存在继续

2.选择复制偏移量最大的节点(复制得最完整,与master节点的数据一致性更高),如果存在则返回,不存在继续

3.如果以上两个条件都不满足,选runId最小的(启动最早的)。

补充一点:还可以向任意sentinel发生sentinel failover <masterName> 进行手动故障转移,这样就不需要经过上述主客观和选举的过程。

猜你喜欢

转载自my.oschina.net/u/3371837/blog/1790026