redis-哨兵模式
在 Redis 主从复制模式中,因为系统不具备自动恢复的功能,所以当主服务器(master)宕机后,需要手动把一台从服务器(slave)切换为主服务器。在这个过程中,不仅需要人为干预,而且还会造成一段时间内服务器处于不可用状态,同时数据安全性也得不到保障,因此主从模式的可用性较低,不适用于线上生产环境。 Redis 官方推荐一种高可用方案,也就是 Redis Sentinel 哨兵模式,它弥补了主从模式的不足。Sentinel 通过监控的方式获取主机的工作状态是否正常,当主机发生故障时, Sentinel 会自动进行 Failover(即故障转移),并将其监控的从机提升主服务器(master),从而保证了系统的高可用性。
哨兵简介
sentinel (哨岗、哨兵)是Redis的高可用性(high availability)解决方案:由一个或多个 Sentinel实例(instance)组成的Sentinel系统(system)可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器, 并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替 已下线的主服务器继续处理命令请求
哨兵的核心功能是主节点的自动故障转移。下面是Redis官方文档对于哨兵功能的描述:
监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。
自动故障转移(Automatic failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
配置提供者(Configuration provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
通知(Notification):哨兵可以将故障转移的结果发送给客户端。
其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置提供者和通知功能,则需要在与客户端的交互中才能体现。
选主的策略简单来说有三个:
-
slave 的 priority 设置的越低,优先级越高;
-
同等情况下,slave 复制的数据越多优先级越高;
-
相同的条件下 runid 越小越容易被选中。
哨兵模式图解
哨兵模式是一种特殊的模式,Redis 为其提供了专属的哨兵命令,它是一个独立的进程,能够独立运行。下面使用 Sentinel 搭建 Redis 集群,基本结构图如下所示:
图1:哨兵基本模式
在上图过程中,哨兵主要有两个重要作用:
-
第一:哨兵节点会以每秒一次的频率对每个 Redis 节点发送
PING
命令,并通过 Redis 节点的回复来判断其运行状态。 -
第二:当哨兵监测到主服务器发生故障时,会自动在从节点中选择一台将机器,并其提升为主服务器,然后使用 PubSub 发布订阅模式,通知其他的从节点,修改配置文件,跟随新的主服务器。
上图所示,多个哨兵之间也存在互相监控,这就形成了多哨兵模式,现在对该模式的工作过程进行讲解,介绍如下:
1) 主观下线
主观下线,适用于主服务器和从服务器。如果在规定的时间内(配置参数:down-after-milliseconds),Sentinel 节点没有收到目标服务器的有效回复,则判定该服务器为“主观下线”。比如 Sentinel1 向主服务发送了PING``PONG
客观下线,只适用于主服务器。 Sentinel1 发现主服务器出现了故障,它会通过相应的命令,询问其它 Sentinel 节点对主服务器的状态判断。如果超过半数以上的 Sentinel 节点认为主服务器 down 掉,则 Sentinel1 节点判定主服务为“客观下线”。
3) 投票选举
投票选举,所有 Sentinel 节点会通过投票机制,按照谁发现谁去处理的原则,选举 Sentinel1 为领头节点去做 Failover(故障转移)操作。Sentinel1 节点则按照一定的规则在所有从节点中选择一个最优的作为主服务器,然后通过发布订功能通知其余的从节点(slave)更改配置文件,跟随新上任的主服务器(master)。至此就完成了主从切换的操作。
哨兵模式应用
主机规划
此教程是redis哨兵模式,使用了三台机器进行部署,如下是主机规划。
主机数量: 3台 配合: 1核1G 系统: centos:7 版本: CentOS Linux release 7.8.2003 (Core) 内核版本: 3.10.0-1127.el7.x86_64 防火墙: 关闭 selinux:关闭(setenforce 0)
IP规划
序号 服务类型 规划IP 备注(端口)
1 redis-master 11.0.1.192 6379
2 sentinel-1 11.0.1.192 26379
3 redis-slave 11.0.1.193 6379
4 sentinel-2 11.0.1.193 26379
5 redis-slave 11.0.1.194 6379
6 sentinel-3 11.0.1.194 26379
redis安装
#安装所需插件 $ yum -y install wget gcc gcc-c++ make tar openssl openssl-devel cmake #使用6.2.4的版本 直接从网上拉取 $wget http://download.redis.io/releases/redis-6.2.4.tar.gz #解压安装 $tar zxf redis-6.2.4.tar.gz $cd /root/redis-6.2.4 $make && make install
redis配置文件
#redis1-master redis.conf bind 0.0.0.0 protected-mode no port 6379 daemonize yes pidfile "/data/sentinel-redis/redis/pidfile/redis_A.pid" logfile "/data/sentinel-redis/logs/redis-A.log" masterauth "123" requirepass "123" --------------------------------------------------------------------------------------- #redis2-slave redis.conf bind 0.0.0.0 protected-mode no port 6379 daemonize yes pidfile "/data/sentinel-redis/redis/pidfile/redis_A.pid" /data/sentinel-redis/redis/pidfile/ logfile "/data/sentinel-redis/logs/redis-A.log" masterauth "123" requirepass "123" replicaof 11.0.1.192 6379 --------------------------------------------------------------------------------------- #redis3-slave redis.conf bind 0.0.0.0 protected-mode no port 6379 daemonize yes pidfile "/data/sentinel-redis/redis/pidfile/redis_A.pid" logfile "/data/sentinel-redis/logs/redis-A.log" masterauth "123" requirepass "123" replicaof 11.0.1.192 6379
启动redis
#在三台主机分别创建log和pid目录并启动redis [root@work1]# mkdir -p /data/sentinel-redis/redis/pidfile/ [root@work1]# mkdir -p /data/sentinel-redis/logs [root@work1]# redis-server redis.conf #查看端口 [root@ork1]# ss -ntlp | grep 6379 LISTEN 0 128 *:6379 *:* users:(("redis-server",pid=2999,fd=6))
测试主从关系是否建立
使用info Replication 查看状态
插入数据进行测试
#在11.0.1.192的redis插入数据 127.0.0.1:6379> set key lili #在11.0.1.193和194的redis查询数据 127.0.0.1:6379> get key "lili" 127.0.0.1:6379>
哨兵安装
哨兵配置文件
#sentinel-1 sentinel.conf port 26379 daemonize yes bind 0.0.0.0 pidfile "./redis-sentinel.pid" logfile "./sentinel.log" protected-mode no sentinel monitor master 11.0.1.192 6379 2 sentinel auth-pass master 123 --------------------------------------------------------------------------------------- #sentinel-2 sentinel.conf port 26379 daemonize yes bind 0.0.0.0 pidfile "./redis-sentinel.pid" logfile "./sentinel.log" protected-mode no sentinel monitor master 11.0.1.192 6379 2 sentinel auth-pass master 123 --------------------------------------------------------------------------------------- #sentinel-3 sentinel.conf port 26379 daemonize yes bind 0.0.0.0 pidfile "./redis-sentinel.pid" logfile "./sentinel.log" protected-mode no sentinel monitor master 11.0.1.192 6379 2 sentinel auth-pass master 123
启动sentinel
[root@work1]# redis-sentinel sentinel.conf [root@work1]# redis-cli -p 26379 127.0.0.1:26379> info Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=master,status=ok,address=11.0.1.192:6379,slaves=2,sentinels=3 #观测状态 目前主节点是11.0.1.192:6379 有两个slave 三个哨兵
故障切换
(1)首先,使用kill命令杀掉主节点:
(2)如果此时立即在哨兵节点中使用info Sentinel命令查看,会发现主节点还没有切换过来,因为哨兵发现主节点故障并转移,需要一段时间。
(3)一段时间以后,再次在哨兵节点中执行info Sentinel查看,发现主节点已经切换成193的6379节点。
但是同时可以发现,哨兵节点认为新的主节点仍然有2个从节点,这是因为哨兵在将193的6379切换成主节点的同时,将192的6379节点置为其从节点;虽然6379从节点已经挂掉,但是由于哨兵并不会对从节点进行客观下线(其含义将在原理部分介绍),因此认为该从节点一直存在。当192的6379节点重新启动后,会自动变成193的6379节点的从节点。下面验证一下。
(4)重启192的6379节点:可以看到192的6379节点成为了193的6379节点的从节点。
(5)在故障转移阶段,哨兵和主从节点的配置文件都会被改写。
对于主从节点,主要是slaveof配置的变化:新的主节点没有了slaveof配置,其从节点则slaveof新的主节点。
对于哨兵节点,除了主从节点信息的变化,纪元(epoch)也会变化,下图中可以看到纪元相关的参数都+1了。
部署总结
有几点需要注意:
(1)哨兵系统中的主从节点,与普通的主从节点并没有什么区别,故障发现和转移是由哨兵来控制和完成的。 (2)哨兵节点本质上是redis节点。 (3)每个哨兵节点,只需要配置监控主节点,便可以自动发现其他的哨兵节点和从节点。 (4)在哨兵节点启动和故障转移阶段,各个节点的配置文件会被重写(config rewrite)。 (5)本章的例子中,一个哨兵只监控了一个主节点;实际上,一个哨兵可以监控多个主节点,通过配置多条sentinel monitor即可实现。
相关命令
#哨兵节点作为运行在特殊模式下的redis节点,其支持的命令与普通的redis节点不同。在运维中,我们可以通过这些命令查询或修改哨兵系统;不过更重要的是,哨兵系统要实现故障发现、故障转移等各种功能,离不开哨兵节点之间的通信,而通信的很大一部分是通过哨兵节点支持的命令来实现的。下面介绍哨兵节点支持的主要命令。 (1)基础查询:通过这些命令,可以查询哨兵系统的拓扑结构、节点信息、配置信息等。 info sentinel:获取监控的所有主节点的基本信息 sentinel masters:获取监控的所有主节点的详细信息 sentinel master mymaster:获取监控的主节点mymaster的详细信息 sentinel slaves mymaster:获取监控的主节点mymaster的从节点的详细信息 sentinel sentinels mymaster:获取监控的主节点mymaster的哨兵节点的详细信息 sentinel get-master-addr-by-name mymaster:获取监控的主节点mymaster的地址信息,前文已有介绍 sentinel is-master-down-by-addr:哨兵节点之间可以通过该命令询问主节点是否下线,从而对是否客观下线做出判断 (2)增加/移除对主节点的监控 sentinel monitor mymaster2 192.168.92.128 16379 2:与部署哨兵节点时配置文件中的sentinel monitor功能完全一样,不再详述 sentinel remove mymaster2:取消当前哨兵节点对主节点mymaster2的监控 (3)强制故障转移 sentinel failover mymaster:该命令可以强制对mymaster执行故障转移,即便当前的主节点运行完好;例如,如果当前主节点所在机器即将报废,便可以提前通过failover命令进行故障转移。