14.Redis 哨兵 Sentinel

Redis 哨兵 Sentinel

  • [Redis 哨兵 Sentinel](#Redis 哨兵 Sentinel)
    • [1. 哨兵 Sentinel 工作原理](#1. 哨兵 Sentinel 工作原理)
    • [2. 实现哨兵架构与具体搭建步骤](#2. 实现哨兵架构与具体搭建步骤)
      • [2.1 准备主从复制环境配置](#2.1 准备主从复制环境配置)
      • [2.2 编辑哨兵配置](#2.2 编辑哨兵配置)
      • [2.3 启动哨兵服务](#2.3 启动哨兵服务)
      • [2.4 验证哨兵服务](#2.4 验证哨兵服务)
      • [2.5 停止 Master 节点实现故障转移](#2.5 停止 Master 节点实现故障转移)
      • [2.6 原 Master 重新加入 Redis 集群](#2.6 原 Master 重新加入 Redis 集群)
    • [3. Sentinel 运维](#3. Sentinel 运维)
    • [4. 应用程序连接 Sentinel](#4. 应用程序连接 Sentinel)
      • [4. 1 客户端连接 Sentinel 工作原理](#4. 1 客户端连接 Sentinel 工作原理)

Redis 哨兵 Sentinel

主从架构和MySQL的主从复制一样,无法实现master和slave角色的自动切换,即当master出现故障时, 不能实现自动的将一个slave节点提升为新的master节点,即主从复制无法实现自动的故障转移功能,如果想实现转移,则需要手动修改配置,才能将 slave 服务器提升新的master节点.此外只有一个主节点支持写操作,所以业务量很大时会导致Redis服务性能达到瓶颈

需要解决的主从复制以下存在的问题:

  • master和slave角色的自动切换,且不能影响业务
  • 提升Redis服务整体性能,支持更高并发访问

1. 哨兵 Sentinel 工作原理

生产环境如果要使用此功能建议使用Redis的2.8版本以上版本

Sentinel 故障转移

  • 多个sentinel发现并确认master有问题。
  • 选举出一个sentinel作为领导。
  • 选出一个slave作为master。
  • 通知其余slave成为新的master的slave。
  • 通知客户端主从变化
  • 等待老的master复活成为新master的slave。

专门的Sentinel 服务进程是用于监控redis集群中Master工作的状态,当Master主服务器发生故障的时候,可以实现Master和Slave的角色的自动切换,从而实现系统的高可用性

Sentinel是一个分布式系统,即需要在多个节点上各自同时运行一个sentinel进程,Sentienl 进程通过流言协议(gossip protocols)来接收关于Master是否下线状态,并使用投票协议(Agreement Protocols)来决定是否执行自动故障转移,并选择合适的Slave作为新的Master

每个Sentinel进程会向其它Sentinel、Master、Slave定时发送消息,来确认对方是否存活,如果发现某个节点在指定配置时间内未得到响应,则会认为此节点已离线,即为主观宕机Subjective Down,简称为 SDOWN

如果哨兵集群中的多数Sentinel进程认为Master存在SDOWN,共同利用 is-master-down-by-addr 命令,互相通知后,则认为客观宕机Objectively Down, 简称 ODOWN

接下来利用投票算法,从所有slave节点中,选一台合适的slave将之提升为新Master节点,然后自动修改其它slave相关配置,指向新的master节点,最终实现故障转移failover

Redis Sentinel中的Sentinel节点个数应该为大于等于3且最好为奇数

客户端初始化时连接的是Sentinel节点集合,不再是具体的Redis节点,即 Sentinel只是配置中心不是代理。

Redis Sentinel 节点与普通 Redis 没有区别,要实现读写分离依赖于客户端程序

Sentinel 机制类似于MySQL中的MHA功能,只解决master和slave角色的自动故障转移问题,但单个 Master 的性能瓶颈问题并没有解决

Redis 3.0 之前版本中,生产环境一般使用哨兵模式较多,Redis 3.0后推出Redis cluster功能,可以支持更大规模的高并发环境

Sentinel中的三个定时任务

  • 每10 秒每个sentinel 对master和slave执行info

    发现slave节点

    确认主从关系

  • 每2秒每个sentinel通过master节点的channel交换信息(pub/sub)

    通过sentinel__:hello频道交互

    交互对节点的"看法"和自身信息

  • 每1秒每个sentinel对其他sentinel和redis执行ping

2. 实现哨兵架构与具体搭建步骤

哨兵需要先实现主从复制

哨兵的前提是已经实现了Redis的主从复制

注意: master 的配置文件中masterauth 和 slave 都必须相同

2.1 准备主从复制环境配置

先通过一键编译脚本在三台主机上安装好redis,搭建一主两从

主机IP 节点
10.0.0.100
10.0.0.101
10.0.0.102
bash 复制代码
# 修改所有主从节点配置文件
[root@ubuntu2204 ~]#vim /apps/redis/etc/redis.conf
bind 0.0.0.0
masterauth 123456
requirepass 123456

# 修改所有从节点配置文件
[root@ubuntu2204 ~]#vim /apps/redis/etc/redis.conf
replicaof 10.0.0.100 6379

# 所有主从节点执行 重启redis服务
[root@ubuntu2204 ~]#systemctl restart redis

# 查看主从节点状态
[root@ubuntu2204 ~]#redis-cli -a 123456 info replication

2.2 编辑哨兵配置

sentinel 配置

Sentinel实际上是一个特殊的redis服务器,有些redis指令支持,但很多指令并不支持.默认监听在 26379/tcp端口.

哨兵服务可以和Redis服务器分开部署在不同主机,但为了节约成本一般会部署在一起

所有redis节点使用相同的以下示例的配置文件

bash 复制代码
# 在源码目录有sentinel.conf,复制到安装目录即可
[root@ubuntu2204 ~]#cp /usr/local/src/redis-7.2.6/sentinel.conf /apps/redis/etc/
[root@ubuntu2204 ~]#ll /apps/redis/etc/

[root@ubuntu2204 ~]#chown redis.redis /apps/redis/etc/sentinel.conf 
[root@ubuntu2204 ~]#ll /apps/redis/etc/

# 修改配置文件
[root@ubuntu2204 ~]#vim /apps/redis/etc/sentinel.conf

protected-mode no
port 26379
daemonize no
pidfile /apps/redis/run/redis-sentinel.pid
logfile "/apps/redis/log/redis-sentinel.log"
dir /apps/redis/data/sentinel

#mymaster是集群的名称,此行指定当前mymaster集群中master服务器的地址和端口
#2为法定人数限制(quorum),即有几个sentinel认为master down了就进行故障转移,一般此值是所有sentinel节点(一般总数是>=3的 奇数,如:3,5,7等)的一半以上的整数值,比如,总数是3,即3/2=1.5,取整为2,是master的ODOWN客观下线的依据
sentinel monitor mymaster 10.0.0.100 6379 2

# mymaster集群中master的密码,注意此行要在上面行的下面
sentinel auth-pass mymaster 123456

# 判断mymaster集群中所有节点的主观下线(SDOWN)的时间,单位:毫秒,建议3000
sentinel down-after-milliseconds mymaster 3000

# #发生故障转移后,可以同时向新master同步数据的slave的数量,数字越小总同步时间越长,但可以减轻新master的负载压力
sentinel parallel-syncs mymaster 1

# 所有slaves指向新的master所需的超时时间,单位:毫秒
sentinel failover-timeout mymaster 180000

acllog-max-len 128

# 禁止修改脚本
sentinel deny-scripts-reconfig yes

SENTINEL resolve-hostnames no

SENTINEL announce-hostnames no
bash 复制代码
# 修改一个节点,其他节点直接scp
[root@ubuntu2204 ~]#scp  /apps/redis/etc/sentinel.conf 10.0.0.101:/apps/redis/etc/

[root@ubuntu2204 ~]#scp  /apps/redis/etc/sentinel.conf 10.0.0.102:/apps/redis/etc/

# 修改scp后的两个sentinel.conf文件的权限
[root@ubuntu2204 ~]#chown redis.redis /apps/redis/etc/sentinel.conf

# 验证三个哨兵服务器的配置
[root@ubuntu2204 ~]#grep -Ev '^#|^$' /apps/redis/etc/sentinel.conf
protected-mode no
port 26379
daemonize no
pidfile /apps/redis/run/redis-sentinel.pid
loglevel notice
logfile "/apps/redis/log/redis-sentinel.log"
dir /apps/redis/data/sentinel
sentinel monitor mymaster 10.0.0.100 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000
acllog-max-len 128
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
SENTINEL resolve-hostnames no
SENTINEL announce-hostnames no
SENTINEL master-reboot-down-after-period mymaster 0

2.3 启动哨兵服务

bash 复制代码
# 生成service文件
[root@ubuntu2204 ~]#vim /lib/systemd/system/redis-sentinel.service

[Unit]
Description=Redis Sentinel
After=network.target

[Service]
ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target

[root@ubuntu2204 ~]#systemctl daemon-reload
[root@ubuntu2204 ~]#systemctl enable --now redis-sentinel.service
[root@ubuntu2204 ~]#systemctl status redis-sentinel.service

注意:
1. 确保权限是redis  
2. Redis Sentinel 配置 daemonize yes 与 --supervised systemd 冲突,导致 systemd 无法管理服务进程,应将 daemonize 改为 no
3. --supervised systemd:表示 Redis Sentinel 由 systemd 管理进程生命周期,Redis 不能自己后台运行

2.4 验证哨兵服务

bash 复制代码
# 查看哨兵服务端口状态
[root@ubuntu2204 run]#ss -nlt

# 查看哨兵日志
[root@ubuntu2204 ~]#tail -f /apps/redis/log/redis-sentinel.log

# 当前sentinel状态
[root@ubuntu2204 ~]#redis-cli -p 26379  info sentinel
# 在sentinel状态中尤其是最后一行,涉及到masterIP是多少,有几个slave,有几个sentinels,必须是符合全部服务器数量
# 两个slave,三个sentinel服务器,如果sentinels值不符合,检查myid可能冲突
master0:name=mymaster,status=ok,address=10.0.0.100:6379,slaves=2,sentinels=3

# 查看 Redis 各节点状态
[root@ubuntu2204 ~]#redis-cli -a 123456  info replication

2.5 停止 Master 节点实现故障转移

bash 复制代码
# 停止 Master 节点
[root@ubuntu2204 ~]#systemctl stop redis

# 变成101
[root@ubuntu2204 ~]#redis-cli -p 26379  info sentinel

master0:name=mymaster,status=ok,address=10.0.0.101:6379,slaves=2,sentinels=3

# 故障转移后从节点redis.conf中的replicaof行的master IP会被修改
[root@ubuntu2204 ~]#grep replicaof /apps/redis/etc/redis.conf
# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# replicaof <masterip> <masterport>
replicaof 10.0.0.101 6379

# 哨兵配置文件的sentinel monitor IP 同样也会被修改
[root@ubuntu2204 ~]#grep 'sentinel monitor' /apps/redis/etc/sentinel.conf
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 10.0.0.101 6379 2


# 验证 Redis 各节点状态
[root@ubuntu2204 ~]#redis-cli -a 123456  info replication
[root@ubuntu2204 ~]#redis-cli -p 26379  info sentinel

2.6 原 Master 重新加入 Redis 集群

bash 复制代码
# 启动redis
[root@ubuntu2204 ~]#systemctl start redis

# 观察状态
[root@ubuntu2204 ~]#grep replicaof /apps/redis/etc/redis.conf
[root@ubuntu2204 ~]#redis-cli -a 123456  info replication
[root@ubuntu2204 ~]#redis-cli -p 26379  info sentinel

3. Sentinel 运维

在Sentinel主机手动触发故障切换

bash 复制代码
[root@ubuntu2204 ~]#vim /apps/redis/etc/redis.conf
replica-priority 80

# 或者动态修改
[root@ubuntu2204 ~]#redis-cli -a 123456
127.0.0.1:6379> CONFIG GET replica-priority
127.0.0.1:6379> CONFIG SET replica-priority 60
127.0.0.1:6379> CONFIG GET replica-priority

# 原主节点自动变成从节点
[root@ubuntu2204 ~]#redis-cli -p 26379
127.0.0.1:26379> sentinel failover mymaster 
OK
127.0.0.1:26379> 

4. 应用程序连接 Sentinel

Redis 官方支持多种开发语言的客户端: https://redis.io/clients

4. 1 客户端连接 Sentinel 工作原理

  • 客户端获取 Sentinel 节点集合,选举出一个 Sentinel
  • 由这个sentinel 通过masterName 获取master节点信息,客户端通过sentinel get-master-addr-by-name master-name这个api来获取对应主节点信息
  • 客户端发送role指令确认master的信息,验证当前获取的"主节点"是真正的主节点,这样的目的是为 了防止故障转移期间主节点的变化
  • 客户端保持和Sentinel节点集合的联系,即订阅Sentinel节点相关频道,时刻获取关于主节点的相关信息,获取新的master 信息变化,并自动连接新的master
相关推荐
努力学习的小廉1 小时前
redis学习笔记(九)—— Redis 持久化
redis·笔记·学习
呆子也有梦1 小时前
redis 的延时双删、双重检查锁定在游戏服务端的使用(伪代码为C#)
redis·后端·游戏·缓存·c#
GDAL2 小时前
BoltDB vs Redis 读性能对比:实测表现与原理差异
redis·boltdb
Fang fan3 小时前
Netty入门
java·开发语言·redis·分布式·python·哈希算法
入瘾4 小时前
Redis 服务启动失败
数据库·redis·缓存
XDHCOM7 小时前
Redis远程连接命令详解,分享高效配置与安全实践技巧
前端·redis·安全
Rsun0455114 小时前
Redis中实现访问量计数
数据库·redis·缓存
摇滚侠18 小时前
限流的方法,Redis 计算器限流算法、滑动时间窗口限流算法、漏漏桶限流算法、令牌桶限流算法,Java 开发
java·数据库·redis
fy1216318 小时前
Redis 下载与安装 教程 windows版
数据库·windows·redis