redis - 哨兵(高可用)提了哨兵的作用以及简单配置,这边就讲一讲他的原理。
哨兵是怎么发现其他哨兵的
哨兵与哨兵之间,是需要知道其他哨兵的健康情况以及信息的分享,我们在前面的配置中,并没有看到其他哨兵地址的配置,只配置了master的地址。哨兵通过redis的Pub/Sub功能,发现也监视的master/slave的其他哨兵。
哨兵会往名字为__sentinel__:hello的Channel里发送hello,此时其他的哨兵就可以接收到消息,并知道其他哨兵的存在。
- 每隔两秒,会向__sentinel__:hello的Channel发送消息,内容包括ip, port, runid。
- Hello消息还包括主服务器的完整当前配置。如果接收哨兵为给定的主服务器配置了比接收到的更老的配置,它会立即更新到新的配置。
- 每个哨兵会监听_sentinel__:hello的Channel的消息,当他发现其他哨兵的信息时,就会被加入哨兵群里。
- 加入哨兵群里之前,他会判断runid是否一样,或者ip+port是否一样,如果一样,旧的信息降被移除,用新的信息替代。
哨兵是怎么知道master挂了
每个哨兵,都会给每个节点发送ping请求(下面只画了master,slave也会发送ping请求),如果节点在down-after-milliseconds(sentinel的配置,比如30秒)内没有响应sentinel-1的ping请求,则我们认为他是主动下线了(SDOWN),如果sentinel-2也发现他没有响应ping请求了,此时两个sentinel大于等于quorum(此时是2),则我们认为他是客观下线了(ODOWN)。也可以这么理解,比如路人甲认为路人乙很坏,可能是因为他跟路人乙有矛盾,主观的认为他坏,其他人可能并不认可他的想法,所以是主观下线。但是路人丙路人丁等多数人觉得路人很坏,那很可能路人乙真的坏,大家的评价是客观的,所以是客观下线。
那我们以什么判断是到达了ODOWN的条件呢,就是我们之前配置的Quorum,但是是否进行故障转移,也要考虑到majority,也就是数量要达到majority才运行授权做故障转移。
比如有5个哨兵,Quorum设置为2,majority设置为3,此时master没响应哨兵的数量为2,已经达到ODOWN的条件了,还是不能做故障转移,只有达到3的时候,才可以做故障转移。
如果Quorum设置为3,majority设置为2,此时master没响应哨兵的数量为2,虽然可以授权做故障转移,但是并没有达到ODOWN的条件,还是不能做故障转移。
哨兵是怎么选举master的
当master被认为是ODOWN的时候,哨兵会通过以下几个选举一个slave为master:
- 从master断开的时间
- slave的优先级
- offset 的值
- Run ID
如果slave和master的断开时间超过down-after-milliseconds的10倍+master的SDOWN的时长,则不考虑切换为master,公示如下:
(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state
slave被选举为master的顺序如下:
- redis.conf配置的优先级,replica-priority越低优先级越高。
- 优先级一样,看offset,offset越大,说明对master的同步数据越多。
- 看offset也一样,则选择runid最小的,选择最小的是为了在选择的时候有更多的确定性,而不是随机选一个。
确定了哪个slave升级为master,那哨兵也是要从哨兵中选举一个来做这些操作的。
- 对应的slave执行slaveof no one,把slave的role移除,变为新的master。
- 通知其他的slav指向新的master。
- 通知应用程序指向新的master。
- 出故障的原master重启后,成为新master的slave节点。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。