运维之道 | Redis 哨兵(Sentinel)深入剖析 及 Sentinel 搭建部署

运维之道 | Redis 哨兵(Sentinel)深入剖析 及 Sentinel 搭建部署

前言

主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主从服务器,这就需要人工干预,既费时费力,还会造成一段时间内服务不可用,这不是一种推荐的方式,更多的时候,我们优先考虑哨兵模式,它是当前企业应用的主流方式。

Redis Sentinel 是 Redis 高可用 的实现方案。Sentinel 是一个管理多个 Redis 实例的工具,它可以实现对 Redis 的 监控、通知、自动故障转移

一、Redis Sentinel 的基本概念

1、Redis 的 主从复制模式Sentinel 高可用架构 的示意图

在这里插入图片描述

2、Redis Sentinel 的架构图

在这里插入图片描述

3、Redis Sentinel的主要功能

Sentinel 的主要功能包括:主节点存活检测主从运行情况检测自动故障转移 (failover)主从切换。Redis 的 Sentinel 最小配置是一主一从;

Redis 的 Sentinel 系统可以用来管理多个 Redis 服务器,该系统可以执行以下四个任务:

  • 监控: Sentinel 会不断的检查 主服务器从服务器 是否正常运行;
  • 通知: 当被监控的某个 Redis 服务器出现问题,Sentinel 通过 API 脚本 向 管理员 或者其他的 应用程序 发送通知;
  • 自动故障转移: 主节点 不能正常工作时,Sentinel 会开始一次 自动的故障转移操作,它会将与失效主节点是主从关系的其中一个从节点升级为新的 主节点,并且将其他的从节点指向新的主节点;
  • 配置提供者: 在 Redis Sentinel 模式下,客户端应用在初始化时连接的是 Sentinel 节点集合,从中获取 主节点 的信息;

4、主观下线和客观下线

默认情况下,每个 Sentinel 节点会以 每秒一次 的频率对 Redis 节点其它 的 Sentinel 节点发送PING 命令,并通过节点的回复来判断节点是否在线

  • 主观下线: 主观下线 适用于所有 主节点从节点。如果在 down-after-milliseconds毫秒内,Sentinel 没有收到 目标节点 的有效回复,则会判定 该节点 为 主观下线;
  • 客观下线: 客观下线 只适用于 主节点。如果 主节点 出现故障,Sentinel 节点会通过 sentinel is-master-down-by-addr 命令,向其它 Sentinel 节点询问对该节点的 状态判断。如果超过 <quorum> 个数的节点判定 主节点 不可达,则该 Sentinel 节点会判断 主节点 为 客观下线

5、Sentinel的通信命令

Sentinel 节点连接一个 Redis 实例的时候,会创建 cmdpub/sub两个 连接。Sentinel 通过 cmd 连接给 Redis 发送命令通过 pub/sub 连接到 Redis 实例上的其他 Sentinel 实例

Sentinel与Redis主节点和从节点交互的命令

命令 作 用
PING Sentinel 向 Redis 节点发送 PING 命令,检查节点的状态
INFO Sentinel 向 Redis 节点发送 INFO 命令,获取它的 从节点信息
PUBLISH Sentinel 向其监控的 Redis 节点 sentinel:hello 这个 channel 发布 自己的信息 及 主节点 相关的配置
SUBSCRIBE Sentinel 通过订阅 Redis 主节点 和 从节点 的 sentinel:hello 这个 channnel,获取正在监控相同服务的其他 Sentinel 节点

Sentinel 与 Sentinel 交互的命令

命令 作 用
PING Sentinel 向其他 Sentinel 节点发送 PING 命令,检查节点的状态
SENTINEL:is-master-down-by-addr 和其他 Sentinel 协商 主节点 的状态,如果 主节点 处于 SDOWN 状态,则投票自动选出新的 主节点

6、Redis Sentinel的工作原理

每个 Sentinel 节点都需要 定期执行 以下任务
每个 Sentinel 以 每秒钟 一次的频率,向它所知的 主服务器从服务器 以及其他 Sentinel 实例 发送一个 PING 命令
在这里插入图片描述
如果一个 实例(instance)距离 最后一次 有效回复 PING 命令的时间超过 down-after-milliseconds 所指定的值,那么这个实例会被 Sentinel 标记为 主观下线
在这里插入图片描述
如果一个 主服务器 被标记为 主观下线,那么正在监视这个主服务器的所有 Sentinel 节点要以每秒一次的频率确认主服务器的确进入了主观下线状态
在这里插入图片描述
如果一个 主服务器 被标记为 主观下线,并且有足够数量的 Sentinel(至少要达到 配置文件 指定的数量)在指定的 时间范围内同意这一判断,那么这个 主服务器 被标记为 客观下线。
在这里插入图片描述
在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率,向它已知的所有 主服务器从服务器发送INFO 命令。当一个 主服务器 被 Sentinel 标记为 客观下线 时,Sentinel 向下线主服务器 的所有从服务器 发送 INFO 命令的频率,会从 10 秒一次改为 每秒一次。
在这里插入图片描述
Sentinel 和其他 Sentinel 协商 主节点 的状态,如果 主节点 处于 SDOWN 状态,则投票自动选出新的 主节点。将剩余的从节点指向新的主节点进行数据复制
在这里插入图片描述
当没有足够数量的 Sentinel 同意主服务器下线时,主服务器的客观下线状态就会被移除。当主服务器重新向Sentinel 的PING命令返回有效回复时主服务器的主观下线状态就会被移除
在这里插入图片描述

注意一个有效的 PING 回复可以是:+PONG、-LOADING 或者 -MASTERDOWN。如果 服务器 返回除以上三种回复之外的其他回复,又或者在 指定时间 内没有回复 PING 命令, 那么 Sentinel 认为服务器返回的回复 无效(non-valid)。


二、Redis Sentinel搭建

1、Redis Sentinel 部署须知

  • 一个稳健的 Redis Sentinel 集群,应该使用至少三个 Sentinel 实例,并且保证讲这些实例放到 不同的机器 上,甚至不同的 物理区域
  • Sentinel 无法保证 强一致性
  • 常见的 客户端应用库 都支持 Sentinel
  • Sentinel 需要通过不断的测试观察,才能保证高可用

2、Redis Sentinel 节点规划

服务类型 主从复制 IP Port
Redis Master 192.168.182.11 16379
Redis slave - 1 192.168.182.11 26379
Redis slave - 2 192.168.182.11 36379
Sentinel - 192.168.182.11 16380
Sentinel - 192.168.182.11 26380
Sentinel - 192.168.182.11 36380

3、Redis-Server (主从复制)配置部署

  • 分别在/usr/local/bin/sentinel目录下创建sentinel-1**、sentinel-2sentinel-3 文件夹**
[root@localhost sentinel]# mkdir sentinel-1 sentinel-2 sentinel-3
[root@localhost sentinel]# ls
sentinel-1  sentinel-2  sentinel-3
  • redis.conf 配置文件分别拷贝至sentinel-1**、sentinel-2sentinel-3 文件夹下**
[root@localhost bin]# cp redis.conf sentinel/sentinel-1
[root@localhost bin]# cp redis.conf sentinel/sentinel-2
[root@localhost bin]# cp redis.conf sentinel/sentinel-3

分别修改三份配置文件如下:

PS:配置文件务必要按顺序修改,否则会报错无法识别master

  • 主节点:redis-16379
daemonize yes
pidfile /var/run/redis-16379.pid
logfile /var/log/redis/redis-16379.log
port 16379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-16379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456
  • 从节点1:redis-26379
daemonize yes
pidfile /var/run/redis-26379.pid
logfile /var/log/redis/redis-26379.log
port 26379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-26379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456
slaveof 127.0.0.1 16379
  • 从节点2:redis-36379
daemonize yes
pidfile /var/run/redis-36379.pid
logfile /var/log/redis/redis-36379.log
port 36379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-36379.db
dir ./redis-workdir
masterauth 123456
requirepass 123456
slaveof 127.0.0.1 16379

PS:如果要做自动故障转移,建议所有的 redis.conf 都设置 masterauth。因为自动故障只会重写主从关系,即slaveof,不会自动写入 masterauth。如果 Redis 原本没有设置密码,则可以忽略。

Redis-Server启动验证

  • 按顺序分别启动redis-1、redis-2、redis-3节点
[root@localhost bin]# redis-server sentinel/sentinel-1/redis.conf 
[root@localhost bin]# redis-server sentinel/sentinel-2/redis.conf 
[root@localhost bin]# redis-server sentinel/sentinel-3/redis.conf 
  • 查看启动进程
root      80625      1  0 15:24 ?        00:00:17 redis-server 0.0.0.0:36379
root      80631      1  0 15:24 ?        00:00:16 redis-server 0.0.0.0:26379
root      82108      1  0 17:22 ?        00:00:01 redis-server 0.0.0.0:16379
  • 主节点redis-16379写入数据,查看从节点1:redis-26379、从节点2:redis-36379是否同步数据
127.0.0.1:16379> set mykeys redis
OK
127.0.0.1:26379> keys *
1) "mykey"
127.0.0.1:36379> keys *
1) "mykey"

主从节点数据已同步,主从复制搭建部署完成


三、Sentinel(哨兵)配置部署

  • sentinel.conf 配置文件分别拷贝至sentinel-1**、sentinel-2sentinel-3 文件夹下**
[root@localhost bin]# cp sentinel.conf sentinel/sentinel-1/
[root@localhost bin]# cp sentinel.conf sentinel/sentinel-2/
[root@localhost bin]# cp sentinel.conf sentinel/sentinel-3/

分别修改三份配置文件如下:

PS:配置文件务必要按顺序修改,否则会报错无法识别master

  • 节点1:sentinel-16380
protected-mode no
bind 0.0.0.0
port 16380
daemonize yes
sentinel monitor master 127.0.0.1 16379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /var/log/redis/sentinel-16380.log
  • 节点2:sentinel-26380
protected-mode no
bind 0.0.0.0
port 26380
daemonize yes
sentinel monitor master 127.0.0.1 16379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /var/log/redis/sentinel-26380.log
  • 节点3:sentinel-36380
protected-mode no
bind 0.0.0.0
port 36380
daemonize yes
sentinel monitor master 127.0.0.1 16379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /var/log/redis/sentinel-36380.log

Sentinel启动验证

  • 按顺序分别启动 16380,2638036380三个Sentinel 节点,启动命令和启动日志如下:
[root@localhost bin]# redis-server sentinel/sentinel-1/sentinel.conf --sentinel
[root@localhost bin]# redis-server sentinel/sentinel-2/sentinel.conf --sentinel
[root@localhost bin]# redis-server sentinel/sentinel-3/sentinel.conf --sentinel
  • 查看 Sentinel 的启动进程:
[root@localhost bin]# ps -ef | grep redis
root      80625      1  0 15:24 ?        00:00:18 redis-server 0.0.0.0:36379
root      80631      1  0 15:24 ?        00:00:17 redis-server 0.0.0.0:26379
root      82108      1  0 17:22 ?        00:00:04 redis-server 0.0.0.0:16379
root      82573      1  0 17:51 ?        00:00:00 redis-server 0.0.0.0:16380 [sentinel]
root      82595      1  0 17:52 ?        00:00:00 redis-server 0.0.0.0:26380 [sentinel]
root      82617      1  0 17:53 ?        00:00:00 redis-server 0.0.0.0:36380 [sentinel]

查看 Sentinel 的启动日志:

  • 节点 sentinel-16380
[root@localhost sentinel-1]# cat sentinel.log 
8166:X 12 Jan 2020 18:42:45.941 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8166:X 12 Jan 2020 18:42:45.941 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=8166, just started
8166:X 12 Jan 2020 18:42:45.941 # Configuration loaded
8167:X 12 Jan 2020 18:42:45.956 * Increased maximum number of open files to 10032 (it was originally set to 1024).
8167:X 12 Jan 2020 18:42:45.957 * Running mode=sentinel, port=16380.
8167:X 12 Jan 2020 18:42:45.957 # Sentinel ID is ddf49c992bceba4fe13eb213bd72aa7db9ff101b
8167:X 12 Jan 2020 18:42:45.957 # +monitor master master 127.0.0.1 16379 quorum 2
8167:X 12 Jan 2020 18:42:48.970 # +sdown master master 127.0.0.1 16379

sentinel-16380 节点的 Sentinel ID 为 ddf49c992bceba4fe13eb213bd72aa7db9ff101b,并通过 Sentinel ID 把自身加入 sentinel 集群中。

  • 节点 sentinel-26380
[root@localhost sentinel-2]# cat sentinel.log 
8180:X 12 Jan 2020 18:42:58.483 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8180:X 12 Jan 2020 18:42:58.483 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=8180, just started
8180:X 12 Jan 2020 18:42:58.483 # Configuration loaded
8181:X 12 Jan 2020 18:42:58.496 * Increased maximum number of open files to 10032 (it was originally set to 1024).
8181:X 12 Jan 2020 18:42:58.496 * Running mode=sentinel, port=26380.
8181:X 12 Jan 2020 18:42:58.496 # Sentinel ID is ddf49c992bceba4fe13eb213bd72aa7db9ff101b
8181:X 12 Jan 2020 18:42:58.496 # +monitor master master 127.0.0.1 16379 quorum 2
8181:X 12 Jan 2020 18:42:58.499 * +slave slave 127.0.0.1:26379 127.0.0.1 26379 @ master 127.0.0.1 16379
8181:X 12 Jan 2020 18:42:58.500 * +slave slave 127.0.0.1:36379 127.0.0.1 36379 @ master 127.0.0.1 16379

可以注意到,sentinel-26380.conf 刷新写入了 Redis 主节点关联的所有 从节点 redis-26379 和 redis-36379,同时写入了其余两个 Sentinel 节点 sentinel-36380 和 sentinel-16380 的 IP 地址,端口号 和 Sentinel ID。


四、哨兵故障切换

Redis Sentinel故障切换

  • kill 杀掉主节点:redis-16379 的进程
[root@localhost sentinel-1]# kill 8757
  • 查看日志(此时主节点已经切换至redis-36379
......
8801:X 12 Jan 2020 19:17:47.631 * +slave slave 127.0.0.1:26379 127.0.0.1 26379 @ master 127.0.0.1 36379
8801:X 12 Jan 2020 19:17:47.631 * +slave slave 127.0.0.1:16379 127.0.0.1 16379 @ master 127.0.0.1 36379
8801:X 12 Jan 2020 19:17:50.668 # +sdown slave 127.0.0.1:16379 127.0.0.1 16379 @ master 127.0.0.1 36379
......
127.0.0.1:26380> sentinel master master

 1) "name"
 2) "master"
 3) "ip"
 4) "127.0.0.1"
 5) "port"
 6) "36379"
 7) "runid"
 8) "15ea078acd8471bf2072a68c1c3f3fc570cb5cca"
 9) "flags"
10) "master"
127.0.0.1:16380> info sentinel

# 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=oup,address=127.0.0.1:36379,slaves=2,sentinels=3

学习至:Redis哨兵模式与高可用集群

发布了97 篇原创文章 · 获赞 10 · 访问量 3350

猜你喜欢

转载自blog.csdn.net/VillianTsang/article/details/103946382