Redis-Sentinel(哨兵)是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

Sentinel 的构造

Sentinel 是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作。
 

sentinel功能

 
监控(Monitoring):
  Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
 
提醒(Notification):
  当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
 
自动故障迁移(Automatic failover):
  当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
 
 

发现并连接主服务器

Sentinel 通过用户给定的配置文件来发现主服务器。
Sentinel 会与被监视的主服务器创建两个网络连接:
  • 命令连接用于向主服务器发送命令。
  • 订阅连接用于订阅指定的频道,从而发现监视同一主服务器的其他 Sentinel (细节马上会介绍)。
 
 

发现并连接从服务器

Sentinel 通过向主服务器发送 INFO 命令来自动获得所有从服务器的地址。
跟主服务器一样,Sentinel 会与每个被发现的从服务器创建命令连接和订阅连接。

发现其他 Sentinel

Sentinel 会通过命令连接向被监视的主从服务器发送 “HELLO” 信息,该消息包含 Sentinel 的 IP、端口号、ID 等内容,以此来向其他 Sentinel 宣告自己的存在。与此同时Sentinel 会通过订阅连接接收其他 Sentinel 的“HELLO” 信息,以此来发现监视同一个主服务器的其他 Sentinel 。
 
sentinel1 通过发送HELLO 信息来让sentinel2 和 sentinel3发现自己,其他两个sentinel 也会进行类似的操作。
 

多个Sentienl之间的链接

Sentinel 之间只会互相创建命令连接,用于进行通信。因为已经有主从服务器作为发送和接收 HELLO 信息的中介,所以 Sentinel之间不会创建订阅连接。

检测实例的状态

 
Sentinel 使用 PING 命令来检测实例的状态:如果实例在指定的时间内没有返回回复,或者返回错误的回复,那么该实例会被 Sentinel 判断为下线。
Redis 的 Sentinel 中关于下线(down)有两个不同的概念:
  1. 主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判断。
  2. 客观下线(Objectively Down, 简称 ODOWN)指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断。 (一个 Sentinel 可以通过向另一个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线。)
如果一个服务器没有在 master-down-after-milliseconds 选项所指定的时间内, 对向它发送 PING 命令的 Sentinel 返回一个有效回复(valid reply), 那么 Sentinel 就会将这个服务器标记为主观下线。

故障转移FAILOVER

一次故障转移操作由以下步骤组成:
  1. 发现主服务器已经进入客观下线状态。
  2. 基于Raft leader election  协议 , 进行投票选举(半数以上)
  3. 如果当选失败,那么在设定的故障迁移超时时间的两倍之后,重新尝试当选。 如果当选成功, 那么执行以下步骤。
  4. 选出一个从服务器,并将它升级为主服务器。
  5. 向被选中的从服务器发送 SLAVEOF NO ONE 命令,让它转变为主服务器。
  6. 通过发布与订阅功能, 将更新后的配置传播给所有其他 Sentinel ,其他 Sentinel 对它们自己的配置进行更新。
  7. 向已下线主服务器的从服务器发送 SLAVEOF 命令,让它们去复制新的主服务器。
  8. 当所有从服务器都已经开始复制新的主服务器时, leader Sentinel 终止这次故障迁移操作。

搭建sentinel环境并且测试主从切换

1. 前提:在搭建之前一定要确认redis主从复制是正常的,这里我们有三个节点6381(主节点)、6380和6382(从节点)
[root@master_1 ~]# redis-cli -a 123 -p 6381 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6382,state=online,offset=19846,lag=1
slave1:ip=127.0.0.1,port=6380,state=online,offset=19846,lag=1
...

主从是ok的

2. sentinel搭建过程
 
mkdir /data/26380
cp /server/tools/redis/src/redis-sentinel /data/26380
cd /data/26380

   

vim sentinel.conf # 官方提供的示例配置文件在redis的安装目录下/server/tools/redis/sentinel.conf
daemonize yes
port 26380
dir "/data/26380"
logfile "/data/26380/sentinel.log"
sentinel monitor mymaster 127.0.0.1 6381 1
sentinel down-after-milliseconds mymaster 3000
sentinel auth-pass mymaster 123

  

注意:如果redis中都设置了密码这里需要加上密码
 
3. 启动
 /data/26380/redis-sentinel /data/26380/sentinel.conf
[21502:X 25 Sep 2019 16:35:52.068 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
21502:X 25 Sep 2019 16:35:52.068 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=21502, just started
21502:X 25 Sep 2019 16:35:52.068 # Configuration loaded
21503:X 25 Sep 2019 16:35:52.073 * Running mode=sentinel, port=26380.
21503:X 25 Sep 2019 16:35:52.082 # Sentinel ID is ff2fe375b2c6dc7e0da91f5bd72743504057c738
21503:X 25 Sep 2019 16:35:52.086 # +monitor master mymaster 127.0.0.1 6381 quorum 1
21503:X 25 Sep 2019 16:35:52.088 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:35:52.090 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6381
已经正常启动sentinel了,并且正常监控到了6381端口,并且获取到了两个slave的状态
 
配置文件详解
指定监控master(名字自己定义)
sentinel monitor mymaster 127.0.0.1 6381 2
{2表示多少个sentinel同意,才确认redis主节点已经下线了。}

安全信息
sentinel auth-pass mymaster 123

超过15000毫秒后认为主机宕机
sentinel down-after-milliseconds mymaster 15000

当主从切换多久后认为主从切换失败
sentinel failover-timeout mymaster 900000

这两个配置后面的数量主从机需要一样,epoch为master的版本
sentinel leader-epoch mymaster 1
sentinel config-epoch mymaster 1

  

4. 停主库测试测试故障切换是否正常:
[root@master_1 26380]# redis-cli -a 123 -p 6381 shutdown

 

查看sentinel的日志信息
21503:X 25 Sep 2019 16:39:26.489 # +sdown master mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:26.489 # +odown master mymaster 127.0.0.1 6381 #quorum 1/1
21503:X 25 Sep 2019 16:39:26.489 # +new-epoch 1
21503:X 25 Sep 2019 16:39:26.489 # +try-failover master mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:26.492 # +vote-for-leader ff2fe375b2c6dc7e0da91f5bd72743504057c738 1
21503:X 25 Sep 2019 16:39:26.492 # +elected-leader master mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:26.492 # +failover-state-select-slave master mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:26.545 # +selected-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:26.545 * +failover-state-send-slaveof-noone slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:26.608 * +failover-state-wait-promotion slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:27.561 # +promoted-slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:27.561 # +failover-state-reconf-slaves master mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:27.625 * +slave-reconf-sent slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:28.589 * +slave-reconf-inprog slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:28.589 * +slave-reconf-done slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:28.689 # +failover-end master mymaster 127.0.0.1 6381
21503:X 25 Sep 2019 16:39:28.689 # +switch-master mymaster 127.0.0.1 6381 127.0.0.1 6380
21503:X 25 Sep 2019 16:39:28.689 * +slave slave 127.0.0.1:6382 127.0.0.1 6382 @ mymaster 127.0.0.1 6380
21503:X 25 Sep 2019 16:39:28.689 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
21503:X 25 Sep 2019 16:39:31.700 # +sdown slave 127.0.0.1:6381 127.0.0.1 6381 @ mymaster 127.0.0.1 6380
可以看出过了3秒后,通过投票选出了新主 6380,然后把6381和6382都指向了6380,指出6381已经挂掉了。
5. 启动源主库(6381)并检查状态。
redis-server /data/6381/redis.conf

  

[root@master_1 26380]# redis-cli -a 123 -p 6381 info replication
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
# Replication
role:slave
master_host:127.0.0.1
master_port:6380
master_link_status:up
...

可以看出sentinel已经把它指定新的redis主

6. 这里有一个需要注意的点就是sentinel会自动修改配置文件
这里我们查一下配置文件
[root@master_1 26380]# cat /data/26380/sentinel.conf
daemonize yes
port 26380
dir "/data/26380"
logfile "/data/26380/sentinel.log"
sentinel myid ff2fe375b2c6dc7e0da91f5bd72743504057c738
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 127.0.0.1 6380 1
# Generated by CONFIG REWRITE
protected-mode no
sentinel down-after-milliseconds mymaster 3000
sentinel auth-pass mymaster 123
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel known-replica mymaster 127.0.0.1 6381
sentinel known-replica mymaster 127.0.0.1 6382

  

Sentinel命令

redis-cli -p 26380 登录执行命令
 
 
PING :返回 PONG 。
SENTINEL masters :列出所有被监视的主服务器
SENTINEL slaves <master name>
SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。
SENTINEL reset <pattern> : 重置所有名字和给定模式 pattern 相匹配的主服务器。
SENTINEL failover <master name> : 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移。

  

 
 
01-19 23:06