「进击Redis」二十五、图解Redis 哨兵模式

1,221 阅读7分钟

前言

Redis 系列第二十五篇,Redis 高可用之哨兵(LOL中最丑的那个英雄,没有之一)模式。讲道理,这个不管在面试(面试经常会问了解过 Redis 的集群模式吗)还是平时维护中还是很有必要理解一下的。当然,要了解哨兵模式的话需要理解一下 Redis 的主从复制,有不了解的好哥哥可以看下深入理解 Redis 主从复制,看完记得点赞加关注哦(手动比心)。
比心

概述

好哥哥们思考一个问题,在 Redis 的主从模式下如果主节点宕机了,而从节点又不提供写操作,这个时候要怎么办?是的这个就是 Redis 主从模式下的一个问题,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址。假设我们生产环境是这么玩的 Redis,那是不是需要停机我们的服务,修改配置后重启服务,这很显然在很多场景中是不能这么玩的。

Redis 为了解决这个问题,在2.8 版本开始正式提供了哨兵模式(下面统称为Sentinel)来解决这个问题。首先Sentinel 其实也是一个 Redis 的服务端程序,这个程序会定时执行一些serverCron函数来获取整个集群模式下的信息,可以在无需人工干预的情况下做到故障转移。另外的话Sentinel 是一个分布式系统,也就是说Sentinel本身也是可以做集群的。

这一篇的话不会涉及到Sentinel 相关的安装与配置操作,主要考虑到都是配置类的东西,面试也不会问你怎么配置Sentinel(我还真遇到过一次),主要还是像原理、运行过程等相关的东西。当然咯,能理解整个配置那就更好了,如果有必要的话后面再补充。

监控机制

监控机制是Sentinel 中非常重要的一部分。Sentinel 要有故障转移能力,那就必须知道所有 Redis 主、从服务器运行时的信息(ip端口号状态等)。在Sentinel 中是通过三个定时监控任务完成对各个节点发现和监控。

1 主从节点信息监控

每隔10秒,每个Sentinel节点会向主节点和从节点发送info命令获取最新的拓扑结构。如下图(忽略psync,这个是主从复制的时候触发):
info

作用
  1. 通过向主节点执行info命令,获取从节点的信息,这也是为什么Sentinel节点不需要显式配置监控从节点。
  2. 当有新的从节点加入时都可以立刻感知出来。
  3. 节点不可达或者故障转移后,可以通过info命令实时更新节点拓扑信息。

2 对主节点监控

每隔2秒,每个Sentinel节点会向 Redis 主节点的__sentinel__:hello频道上发送该Sentinel节点对于主节点的判断以及当前Sentinel节点的信息,同时每个Sentinel节点也会订阅该频道,来了解其他Sentinel节点以及它们对主节点的判断。 在这里插入图片描述

作用
  1. 通过订阅主节点的__sentinel__:hello了解其他的Sentinel节点信息,如果是新加入的Sentinel节点将该Sentinel节点信息保存起来,并与该Sentinel节点创建连接。
  2. Sentinel节点之间交换主节点的状态,作为后面客观下线(这个后面会说)以及领导者选举的依据。

3 心跳检测

每隔1秒,每个Sentinel节点会向主节点从节点、其余Sentinel节点发送一条ping命令做一次心跳检测,来确认这些节点当前是否可达。这个定时任务是节点失败判定的重要依据。
ping

主观和客观下线

主观下线

上面最后一个定时任务中有提到Sentinel节点会每隔1秒对主节点从节点其他Sentinel节点发送ping命令做心跳检测,当这些节点超过down-after-milliseconds(配置文件中的属性)没有进行有效回复,Sentinel节点就会对该节点做失败判定,这个行为叫做主观下线(站在一个Sentinel的角度上,当前Sentinel认为下线就是主观)。

客观下线

Sentinel主观下线的节点是主节点时,该 Sentinel 节点会通过sentinel is-master-down-by-addr命令向其他Sentinel节点询问对主节点的判断,当超过quorum个数,Sentinel节点认为主节点确实有问题,这时该Sentinel节点会做出客观下线的决定,这样客观下线的含义是比较明显了,也就是大部分Sentinel节点都对主节点的下线做了同意的判定,那么这个判定就是客观的。

Sentinel 选举

Sentinel 客观判定认为主节点下线后,是不会立刻执行 Redis 的故障转移,因为执行故障转移只需要一个Sentinel来操作。那该由哪一个Sentinel来执行呢?这个时候就会出现一个选举Leader的过程。

在 Redis 中使用了Raft算法来实现对Leader的选举,由于Raft算法既抽象又复杂,这里就不详细展开来说,大概讲一下Sentinel 选举的过程,如下:

  1. 每个在线的Sentinel节点都有资格成为领导者,当它确认主节点主观下线时候,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令,要求将自己设置为领导者。
  2. 收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的sentinelis-master-down-by-addr命令,将同意该请求,否则拒绝。
  3. 如果该Sentinel节点发现自己的票数已经大于等于num / 2 + 1 (numSentinel节点个数),那么它将成为领导者。
  4. 如果此过程没有选举出Leader,将进入下一次选举。

raft

故障转移

上面也提到了,实际上Sentinel的作用就是用来做故障转移的。现在Sentinel客观下线了主节点,上面也把SentinelLeader选举出来了,最后的步骤就是通过这个Leader来操作故障转移。大概过程如下:

  1. 选择合适的从节点 因为整个集群环境存在多个从节点,所以Sentinel 在操作故障转移过程时会有一个过滤从节点的过程,选择合适的一台从节点提升为主节点,步骤如下:
    1.1 过滤掉主观下线、5 秒内没有回复过Sentinel 节点ping 响应、与主节点失联超过down-after-milliseconds*10 秒的从节点。
    1.2 选择slave-priority (从节点优先级)最高的从节点列表,如果存在则返回,不存在则继续。
    1.3 选择复制偏移量最大的从节点(复制的最完整),如果存在则返回,不存在则继续。
    1.4 选择runid 最小的从节点。
  2. Sentinel领导者节点会对第一步选出来的从节点执行slaveof no one命令让其成为主节点。
  3. Sentinel领导者节点会向剩余的从节点发送命令,让它们成为新主节点的从节点,复制规则和parallel-syncs参数有关。
  4. Sentinel节点集合会将原来的主节点更新为从节点,并保持着对其关注,当其恢复后命令它去复制新的主节点。

局限性

  1. 部署麻烦、原理复杂、浪费资源,从节点作为备份节点不提供服务。
  2. 不支持读写分离,实现起来相对复杂。
  3. 只支持对主节点的故障转移,不支持对从节点的故障转移。
  4. 存储的数据量有限,因为Sentinel的基础是主从复制,所有主节点和从几点都包含了 Redis 全量的数据。

总结

关于Sentinel就先到这吧,Sentinel的安装与部署的话这个后面可能会加上去(可能性不大,别打脸好哥哥们)。主要把上面的监控机制、SentinelLeader选举、故障转移概念和流程搞清楚问题就不大。如果觉得图画的不错就点个赞加个关注吧(疯狂暗示)。

本期就到这啦,有不对的地方欢迎好哥哥们评论区留言,另外求关注、求点赞 下一篇: 你竟然还不知道 hash slot | 七日打卡
上一篇: 深入理解 Redis 主从复制