介绍

哨兵(sentinel),用于对主从结构中的每一台服务器进行监控,当主节点出现故障后通过投票机制来挑选新的主节点,并且将所有的从节点连接到新的主节点上。

在 Redis 主从复制模式中,因为系统不具备自动恢复的功能,所以当主服务器(master)宕机后,需要手动把一台从服务器(slave)切换为主服务器。在这个过程中,不仅需要人为干预,而且还会造成一段时间内服务器处于不可用状态,同时数据安全性也得不到保障,因此主从模式的可用性较低,不适用于线上生产环境。

Redis 官方推荐一种高可用方案,也就是 Redis Sentinel 哨兵模式,它弥补了主从模式的不足。Sentinel 通过监控的方式获取主机的工作状态是否正常,当主机发生故障时, Sentinel 会自动进行 Failover(即故障转移),并将其监控的从机提升主服务器(master),从而保证了系统的高可用性。

作用

  • 监控:监控主从节点运行情况。
  • 通知:当监控节点出现故障,哨兵之间进行通讯。
  • 自动故障转移:当监控到主节点宕机后,断开与宕机主节点连接的所有从节点,然后在从节点中选取一个作为主节点,将其他的从节点连接到这个最新的主节点。最后通知客户端最新的服务器地址。

哨兵节点最少三台且必须为单数。这个与其他分布式框架如zookeeper类似,如果是双数,在选举的时候就会出现平票的情况,所以必须是三台及以上的单数。

也支持多个master-slave结构:

原理

哨兵模式是一种特殊的模式,Redis 为其提供了专属的哨兵命令,它是一个独立的进程,能够独立运行。下面使用 Sentinel 搭建 Redis 集群,基本结构图如下所示:

哨兵之间会有通讯,哨兵和主从节点之间也有监控,基于这些信息同步和状态监控实现Redis的故障转移:

  • 哨兵和哨兵之间以及哨兵和Redis主从节点之间每隔一秒发送ping监控它们的健康状态;
  • 哨兵向Redis主从节点每隔10秒发送一次info保存节点信息;
  • 哨兵向Redis主节点每隔2秒发送一次hello,直到哨兵报出sdown,代表主节点失联,然后通知其余哨兵尝试连接该主节点;

Redis主节点下线的情况分为主观下线和客观下线:
主观下线(sdown):单独一个哨兵发现master故障了。
客观下线(odown):半数哨兵都认为master节点故障就会触发故障转移。

在实际生产情况中,Redis Sentinel 是集群的高可用的保障,为避免 Sentinel 发生意外,它一般是由 3~5 个节点组成,这样就算挂了个别节点,该集群仍然可以正常运转。其结构图如下所示:

上图所示,多个哨兵之间也存在互相监控,这就形成了多哨兵模式,现在对该模式的工作过程进行讲解,介绍如下:

1) 主观下线

主观下线,适用于主服务器和从服务器。如果在规定的时间内(配置参数:down-after-milliseconds),Sentinel 节点没有收到目标服务器的有效回复,则判定该服务器为“主观下线”。比如 Sentinel1 向主服务发送了PING命令,在规定时间内没收到主服务器PONG回复,则 Sentinel1 判定主服务器为“主观下线”。

2) 客观下线

客观下线,只适用于主服务器。 Sentinel1 发现主服务器出现了故障,它会通过相应的命令,询问其它 Sentinel 节点对主服务器的状态判断。如果超过半数以上的 Sentinel 节点认为主服务器 down 掉,则 Sentinel1 节点判定主服务为“客观下线”。

3) 投票选举

投票选举,所有 Sentinel 节点会通过投票机制,按照谁发现谁去处理的原则,选举 Sentinel1 为领头节点去做 Failover(故障转移)操作。Sentinel1 节点则按照一定的规则在所有从节点中选择一个最优的作为主服务器,然后通过发布订功能通知其余的从节点(slave)更改配置文件,跟随新上任的主服务器(master)。至此就完成了主从切换的操作。

对上对述过程做简单总结:

Sentinel 负责监控主从节点的“健康”状态。当主节点挂掉时,自动选择一个最优的从节点切换为主节点。客户端来连接 Redis 集群时,会首先连接 Sentinel,通过 Sentinel 来查询主节点的地址,然后再去连接主节点进行数据交互。当主节点发生故障时,客户端会重新向 Sentinel 要地址,Sentinel 会将最新的主节点地址告诉客户端。因此应用程序无需重启即可自动完成主从节点切换。

哨兵Leader选举:

一般情况下当哨兵发现主节点sdown之后 该哨兵节点会成为领导者负责处理主从节点的切换工作:

  1. 哨兵A发现Redis主节点失联;
  2. 哨兵A报出sdown,并通知其他哨兵,发送指令sentinel is-master-down-by-address-port给其余哨兵节点;
  3. 其余哨兵接收到哨兵A的指令后尝试连接Redis主节点,发现主节点确实失联;
  4. 哨兵返回信息给哨兵A,当超过半数的哨兵认为主节点下线后,状态会变成odown;
  5. 最先发现主节点下线的哨兵A会成为哨兵领导者负责这次的主从节点的切换工作;

哨兵的选举机制是以各哨兵节点接收到发送sentinel is-master-down-by-address-port指令的哨兵id 投票,票数最高的哨兵id会成为本次故障转移工作的哨兵Leader;

故障转移:

当哨兵发现主节点下线之后经过上面的哨兵选举机制,选举出本次故障转移工作的哨兵节点完成本次主从节点切换的工作:

  1. 哨兵Leader 根据一定规则从各个从节点中选择出一个节点升级为主节点;
  2. 其余从节点修改对应的主节点为新的主节点;
  3. 当原主节点恢复启动的时候,变为新的主节点的从节点

哨兵Leader选择新的主节点遵循下面几个规则:
健康度:从节点响应时间快;
完整性:从节点消费主节点的offset偏移量尽可能的高 ();
稳定性:若仍有多个从节点,则根据从节点的创建时间选择最有资历的节点升级为主节点;

在哨兵模式下主从节点总是会变更,因此在Java或Python中访问哨兵模式下的Redis时可以使用对应的哨兵接口连接:


#Java
JedisSentinelPool

#Python
from redis.sentinel import SentinelConnectionPool

手动主从切换

当主节点出现宕机时,这时候最简单的方式可以使用主从手动切换的方式,手动的将一台从节点切换成主节点,所以我们需要人工干预手动设置,最关键在手动切换的过程中会造成Redis服务不可用。所以说主从手动切换的方案不是一个合适的主从切换方案,但是我们也来看下主从手动切换是如何实现的。

当主节点出现宕机,这时候我们需要手动将从节点设置成主节点。命令:

redis-cli -h <从节点ip> -p <从节点端口号> slaveof no one
redis-cli -h 127.0.0.1 -p 6379 slaveof no one

通过上面命令,可以将该从节点临时设置为主节点。当Redis重启时,主从切换设置将会失效。然后按照上一篇主从复制的配置将其他从节点的主配置改成现在的主节点。当原来的主节点从宕机中进行恢复,则将临时主节点的数据进行保存,将AOF文件与RDB文件拷贝替换原主节点下的AOF文件与RDB文件。然后重启原主节点Redis服务以及临时主节点Redis服务,恢复原先的主从关系。但是毕竟主从手动切换方案是存在问题的不是很适用,所以一般主从切换会采用哨兵模式。

————————————————
版权声明:本文为CSDN博主「王义凯_Rick」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wsdc0521/article/details/106765909

参考资料:
https://www.freesion.com/article/9409248898/
https://blog.csdn.net/qq_25086397/article/details/126246777
https://www.bbsmax.com/A/1O5E3pP3z7/

作者:Jeebiz  创建时间:2022-10-16 17:13
最后编辑:Jeebiz  更新时间:2024-08-16 11:14