3.哨兵

从数据库可以进行数据备份和读写分离。主数据库宕机,需要手动把从数据库切换成主数据库。而哨兵可以实现自动切换。

3.1 哨兵功能

  1. 监控主从库是否运行正常,打印日志
  2. 主数据库出现故障自动将从数据库升级为主数据库。主数据库短线重连后自动成为新主数据库的从数据库。

3.2 配置哨兵

  1. 在copy下新建文件夹sentinel存放配置文件。
[root@localhost ~]# cd /redis/redis-5.0.0/copy/
[root@localhost copy]# mkdir sentinel
  1. 新建配置文件sentinel.conf,写入
[root@localhost copy]# cd sentinel
[root@localhost sentinel]# ll
total 0
[root@localhost sentinel]# vim sentinel.conf
//写入内容,congige是给这个主数据库起的名字
sentinel monitor confige 127.0.0.1 6379 1

主数据名字必须由大小写字母、数字和“.-_”这三个字符组成

  1. 启动sentinel
[root@localhost sentinel]# redis-sentinel sentinel.conf 
4768:X 05 Feb 2020 16:45:01.732 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
4768:X 05 Feb 2020 16:45:01.732 # Redis version=5.0.0, bits=64, commit=00000000, modified=0, pid=4768, just started
.
.
.
4768:X 05 Feb 2020 16:45:01.735 # Sentinel ID is 39ba7fa9f49c9b9f238f27cc2487edde1ec199b9
4768:X 05 Feb 2020 16:45:01.735 # +monitor master confige 127.0.0.1 6379 quorum 1
4768:X 05 Feb 2020 16:45:01.736 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ confige 127.0.0.1 6379
4768:X 05 Feb 2020 16:45:01.738 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ confige 127.0.0.1 6379

哨兵配置参数解释:
参考 sentinel monitor
告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效
sentinel auth-pass
设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
sentinel down-after-milliseconds
这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒
sentinel parallel-syncs
这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行 同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越 多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态。
sentinel failover-timeout
failover-timeout 可以用在以下这些方面:
a. 同一个sentinel对同一个master两次failover之间的间隔时间。
b. 当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
c.当想要取消一个正在进行的failover所需要的时间。
d.当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。

  1. 我们把主库关闭,看下输出;
[root@localhost ~]# ps -ef|grep redis
root       2203      1  0 13:31 ?        00:00:55 redis-server *:6379
root       2327      1  0 13:37 ?        00:00:44 redis-server *:7000
root       2622      1  0 13:52 ?        00:00:45 redis-server *:6380
root       3485   3249  0 14:47 pts/7    00:00:00 redis-cli -p 6379
root       3823      1  0 15:14 ?        00:00:27 redis-server 127.0.0.1:6381
root       4768   3177  0 16:45 pts/6    00:00:10 redis-sentinel *:26379 [sentinel]
root       5072   3436  0 17:11 pts/8    00:00:00 grep --color=auto redis
[root@localhost ~]# kill -9 2203

输入内容如下

//6379端口对应节点1主观下线
4768:X 05 Feb 2020 17:12:24.564 # +sdown master confige 127.0.0.1 6379
//节点1客观下线
4768:X 05 Feb 2020 17:12:24.564 # +odown master confige 127.0.0.1 6379 #quorum 1/1
4768:X 05 Feb 2020 17:12:24.564 # +new-epoch 1
//哨兵开始故障恢复
4768:X 05 Feb 2020 17:12:24.564 # +try-failover master confige 127.0.0.1 6379
//开始选举领头哨兵
4768:X 05 Feb 2020 17:12:24.565 # +vote-for-leader 39ba7fa9f49c9b9f238f27cc2487edde1ec199b9 1
//选出领头哨兵
4768:X 05 Feb 2020 17:12:24.565 # +elected-leader master confige 127.0.0.1 6379
//选节点1作为主数据库
4768:X 05 Feb 2020 17:12:24.565 # +failover-state-select-slave master confige 127.0.0.1 6379
//选择6381端口对应节点3为从数据库数据库
4768:X 05 Feb 2020 17:12:24.650 # +selected-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ confige 127.0.0.1 6379
4768:X 05 Feb 2020 17:12:24.650 * +failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1 6381 @ confige 127.0.0.1 6379
4768:X 05 Feb 2020 17:12:24.728 * +failover-state-wait-promotion slave 127.0.0.1:6381 127.0.0.1 6381 @ confige 127.0.0.1 6379
4768:X 05 Feb 2020 17:12:25.131 # +promoted-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ confige 127.0.0.1 6379
4768:X 05 Feb 2020 17:12:25.131 # +failover-state-reconf-slaves master confige 127.0.0.1 6379
4768:X 05 Feb 2020 17:12:25.211 * +slave-reconf-sent slave 127.0.0.1:6380 127.0.0.1 6380 @ confige 127.0.0.1 6379
4768:X 05 Feb 2020 17:12:26.151 * +slave-reconf-inprog slave 127.0.0.1:6380 127.0.0.1 6380 @ confige 127.0.0.1 6379
4768:X 05 Feb 2020 17:12:26.151 * +slave-reconf-done slave 127.0.0.1:6380 127.0.0.1 6380 @ confige 127.0.0.1 6379
//完成故障恢复
4768:X 05 Feb 2020 17:12:26.214 # +failover-end master confige 127.0.0.1 6379
4768:X 05 Feb 2020 17:12:26.214 # +switch-master confige 127.0.0.1 6379 127.0.0.1 6381
4768:X 05 Feb 2020 17:12:26.215 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ confige 127.0.0.1 6381
4768:X 05 Feb 2020 17:12:26.215 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ confige 127.0.0.1 6381
4768:X 05 Feb 2020 17:12:56.237 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ confige 127.0.0.1 6381
  1. 重启实例A
[root@localhost redis-5.0.0]# redis-server redis.conf 
5154:C 05 Feb 2020 17:17:37.481 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5154:C 05 Feb 2020 17:17:37.481 # Redis version=5.0.0, bits=64, commit=00000000, modified=0, pid=5154, just started
5154:C 05 Feb 2020 17:17:37.481 # Configuration loaded

看下哨兵输出

//发现节点
4768:X 05 Feb 2020 17:17:38.190 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ confige 127.0.0.1 6381
//把节点转为新主节点的从节点
4768:X 05 Feb 2020 17:17:48.198 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ confige 127.0.0.1 6381

3.3 哨兵原理

哨兵启动时会读取配置文件的内容
sentinel monitor confige 127.0.0.1 6379 1
故障恢复后,主数据库的ip地址和端口号可能改变,所以可以通过主数据库名字去获取ip和端口号信息
sentinel.conf初始化后多了很多内容,现在加上daemonize使它可以后台运行

[root@localhost sentinel]# vim sentinel.conf

sentinel myid 39ba7fa9f49c9b9f238f27cc2487edde1ec199b9
# Generated by CONFIG REWRITE
port 26379
dir "/redis/redis-5.0.0/copy/sentinel"
sentinel deny-scripts-reconfig yes
sentinel monitor confige 127.0.0.1 6381 1
sentinel config-epoch confige 1
sentinel leader-epoch confige 1
sentinel known-replica confige 127.0.0.1 6379
sentinel known-replica confige 127.0.0.1 6380
sentinel current-epoch 1

修改sentinel配置文件后重启

[root@localhost sentinel]# redis-sentinel sentinel.conf 
6117:X 05 Feb 2020 18:43:34.891 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
6117:X 05 Feb 2020 18:43:34.892 # Redis version=5.0.0, bits=64, commit=00000000, modified=0, pid=6117, just started
6117:X 05 Feb 2020 18:43:34.892 # Configuration loaded
//查看进程号,端口,服务
[root@localhost sentinel]# ps -ef|grep redis
root       2327      1  0 13:49 ?        00:01:01 redis-server *:7000
root       2622      1  0 14:04 ?        00:01:04 redis-server *:6380
root       3485   3249  0 15:00 pts/7    00:00:00 redis-cli -p 6379
root       3823      1  0 15:26 ?        00:00:48 redis-server 127.0.0.1:6381
root       5155      1  0 17:29 ?        00:00:17 redis-server 127.0.0.1:6379
root       6118      1  1 18:43 ?        00:00:00 redis-sentinel *:26379 [sentinel]
root       6131   5851  0 18:43 pts/0    00:00:00 grep --color=auto redis
[root@localhost sentinel]# redis-cli -p 26379
//查看主节点信息
127.0.0.1:26379> 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=confige,status=ok,address=127.0.0.1:6381,slaves=2,sentinels=1
127.0.0.1:26379>
  1. 哨兵启动后,会与要监控的主数据库建立两条连接
    (1)订阅主数据库的_sentinel_:hello 频道获取同样监控这个主数据库节点的包括自己的哨兵节点信息;
    (2)定期向主数据库发送INFO等命令获取主数据库节点本身的信息
  2. 和主数据库建立连接后,哨兵会定时执行下面3个操作
    (1)每隔10秒会向主数据库和从数据库发送INFO命令。
    (2)每隔2秒哨兵会向主数据库和从数据库的_sentinel_:hello频道发送自己的信息
    (3)每隔1秒会向主数据库、从数据库和其他哨兵节点发送PING命令
    sentinel down-after-milliseconds 10000
    设置发送命令的间隔,大于等于1000ms设置发送命令的间隔,大于等于1000ms都是1s间隔