Sentinel(哨兵模式)
经过上期【Redis】主从复制 的学习,
我们知道 主从复制 是为了避免单点故障,将数据保存在多台服务器上的一种机制。
但是主节点只有一个,如果主节点挂掉了,怎么办?于是 哨兵模式 诞生了。
哨兵模式可以不时地监控 redis
是否按照预期良好的运行(至少是保证主节点是存在的),若一台主机出现问题,哨兵会自动将该主机下的某一从机设置为新的主机,并让其他从机和新主机建立主从关系。
《Redis 设计与实现》哨兵模式介绍:
Sentinel(哨兵)是Redis的高可用性解决方案:由一个或多个 Sentinel 实例组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新主服务器,然后由新的主服务器替代已下线的主服务器继续处理命令请求。
Sentinel(哨兵) 本质上只是一个运行在特殊模式下的Redis服务器,但是因为Sentinel(哨兵)并不使用数据库,所以初始化Sentinel(哨兵)时就不会载入RDB
文件或者AOF
文件。
哨兵模式架构模型:
哨兵模式的三个定时任务
- 每10秒每个Sentinel(哨兵)向主从节点发送info命令,用来获取最新的主从结构
- 每2秒每个Sentinel(哨兵)通过master节点的channel交换信息,channel是发布订阅的频道,可以获取其他哨兵节点的信息。
-
每1秒Sentinel(哨兵)向与它创建了命令连接的实例(主、从服务器,其他Sentinel)发送
PING
命令,用来进行心跳检测,判断是否下线
Sentinel(哨兵)与Sentinel 、主服务器、从服务器之间的连接
Sentinel(哨兵)在连接主服务器 或者 从服务器时,会同时创建命令连接
和 订阅连接
,命令连接用来 向 主服务器 和 从服务器发送消息,而订阅连接用来接收来自主服务器和从服务器的信息。
但是在连接其他Sentinel(哨兵)时只会创建命令连接,而不创建订阅连接。这是因为Sentinel(哨兵)需要通过接收主服务器或者从服务器发来的信息发现未知的新Sentinel ,而相互已知的Sentinel只要用命令连接来进行通信就足够了。
检测下线状态
如果只有一个Sentinel(哨兵),那么可能会又出现单点故障的问题,所以一般设置多个Sentinel(哨兵)来监视。此外,这些不同的哨兵节点应部署在不同的物理机上。
在默认情况下Sentinel(哨兵)会以每秒一次的频率向与它创建了命令连接的实例(主、从服务器,其他Sentinel)发送PING
命令,并通过回复来判断实例是否在线。
当Sentinel(哨兵)将一个主服务器判断为下线后,为主观下线。为了确定这个主服务器是否真的下线了,他会向同样监视这一主服务器的其他Sentinel(哨兵)进行询问,看他们是否也认为主服务器已经进入了下线状态。如果多个哨兵(设置一个阈值)都认为 master 异常了,就会认为master 判定为客观下线,并对主服务器执行故障转移操作。
注意,这里客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。
选择领头 Sentinel(哨兵)
当主节点被判断客观下线以后,各个哨兵节点会进行协商,选举出一个领导者哨兵节点,并由该领导者节点对其进行故障转移操作。
监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是 Raft 算法。选举规则:
每个哨兵都询问其它哨兵,请求对方为自己投票
每个哨兵只投票给第一个请求投票的哨兵,且只能投票一次
首先拿到超过半数投票的哨兵,当选为领导者,发起主从切换
故障转移
选举出的领导者哨兵,开始进行故障转移操作,该操作大体可以分为 3 个步骤:选出新的主服务器、修改从服务器的复制目标、将旧的主服务器变为从服务器
-
选出新的主服务器
选择新的主服务器,领头Sentinel 会将已下线主服务器所有从服务器保存到一个列表里面,按以下规则选出:
删除列表中所有处于下线或者断线状态的从服务器,保证列表中剩余都是正常在线的。
删除最近5秒内没有恢复INFO命令的从服务器,保证列表中剩余的都是最近成功进行通信的。
删除与已下线主服务器断开时长超过 10 *
down-after-milliseconds
毫秒的从服务器,保证列表中剩余的从服务器保存的数据都是比较新的。之后根据从服务器的优先级,选出优先级最高的从服务器。
如果有多个相同优先级的从服务器,那么领头Sentinel选出复制偏移量最大的从服务器(偏移量越大保存的数据越新)
最后,如果有多个优先级最高、复制偏移量最大的从服务器,那么领头Sentinel按照运行ID 排序,选择运行ID 最小的从服务器
-
修改从服务器的复制目标
当新主服务器出现后,领头Sentinel下一步会让已下线主服务器属下所有从服务器去复制新的主服务器
-
将旧的主服务器变为从服务器
最后要做的是,将旧的主服务器变为从服务器。当其重新上线时变为新的主服务器的从服务器。
缺点
哨兵仍然没有解决写操作无法负载均衡、及存储能力受到单机限制的问题;这些问题的解决需要使用集群
本文没有详细说明 Sentinel 的初始化过程,详细请看《Redis 设计与实现》第16章。
参考:
《Redis 设计与实现》