前言
在之前的主从辅助中有提到,如果从库发生故障,从库重连后会借助repl_backlog_buffer这个环形缓冲区实现增量复制,来达到数据相同的操作。
但是主库挂了怎么办?我们的redis服务总不可能只提供读服务吧(主库挂了从库仍可读),redis的哨兵机制有效的解决了这个问题
利用docker快速搭建(1主3从)
-
文件夹创建
image.png
data中的文件忽略,运行时生成,redis.conf和sentinel.conf都可以从redis安装包中获取
- redis.conf文件修改
参考主从复制这个连接分别对slave的redis.conf文件修改
- 各自运行docker容器创建脚本
这里以master.sh为例
#! /bin/bash
docker run -d -p 6379:6379 -p 26379:26379 --name master -v /home/docker/redis/master/conf:/etc/redis/conf -v /home/docker/redis/master/data:/data redis:5.0.5 redis-server /etc/redis/conf/redis.conf
要开放26379端口为哨兵进程使用(哨兵进程说白了就是个监听主实例运行状况的进程)
./master,sh
- 修改sentinel.conf
daemonize yes
logfile "26379.log"
dir "/data"
//mymaster为自定义主实例名
sentinel monitor mymaster 172.17.0.2 6379 2 //主实例ip,2表示要至少获得2票才能升级为主实例通常为N/2+1
//下面这条必须出现在上面这条之后,因为上面这条定义mymaster
sentinel auth-pass mymaster 123456
//每5秒查询一次
sentinel config-epoch mymaster 5000
sentinel leader-epoch mymaster 5000
分别进入容器运行sentinel
docker exec -it master /bin/bash
redis-sentinel /etc/conf/sentinel.conf
观察日志
cat ./data/26479.log
26:X 01 Mar 2021 18:48:49.874 # Configuration loaded
27:X 01 Mar 2021 18:48:49.877 * Running mode=sentinel, port=26379.
27:X 01 Mar 2021 18:48:49.877 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
27:X 01 Mar 2021 18:48:49.877 # Sentinel ID is 34b8927f010859b412667d9152e8aab034d0162e
27:X 01 Mar 2021 18:48:49.877 # +monitor master mymaster 172.17.0.2 6379 quorum 2
27:X 01 Mar 2021 18:48:49.878 * +slave slave 172.17.0.3:6379 172.17.0.3 6379 @ mymaster 172.17.0.2 6379
27:X 01 Mar 2021 18:48:49.883 * +slave slave 172.17.0.4:6379 172.17.0.4 6379 @ mymaster 172.17.0.2 6379
- 查看主从信息
docker exec -it master redis-cli
> info replication
- 挂掉主实例
docker stop master
docker exec -it slave1 redis-cli
> info replication //从实例1被升级为主实例
查看日志
//主实例挂掉
23:X 01 Mar 2021 18:54:54.599 # +sdown master mymaster 172.17.0.2 6379
//从实例被投票升级为主实例
23:X 01 Mar 2021 18:54:55.720 # +odown master mymaster 172.17.0.2 6379 #quorum 2/2
23:X 01 Mar 2021 18:54:55.720 # Next failover delay: I will not start a failover before Mon Mar 1 19:00:54 2021
23:X 01 Mar 2021 18:54:55.745 # +config-update-from sentinel 44da4a8b09cc2f86daa314ebe04500df9fd8c656 172.17.0.4 26379 @ mymaster 172.17.0.2 6379
23:X 01 Mar 2021 18:54:55.745 # +switch-master mymaster 172.17.0.2 6379 172.17.0.3 6379
23:X 01 Mar 2021 18:54:55.746 * +slave slave 172.17.0.5:6379 172.17.0.5 6379 @ mymaster 172.17.0.3 6379
23:X 01 Mar 2021 18:54:55.746 * +slave slave 172.17.0.4:6379 172.17.0.4 6379 @ mymaster 172.17.0.3 6379
23:X 01 Mar 2021 18:54:55.746 * +slave slave 172.17.0.2:6379 172.17.0.2 6379 @ mymaster 172.17.0.3 6379
23:X 01 Mar 2021 18:55:25.811 # +sdown slave 172.17.0.2:6379 172.17.0.2 6379 @ mymaster 172.17.0.3 6379
23:X 01 Mar 2021 18:55:58.127 # -sdown slave 172.17.0.2:6379 172.17.0.2 6379 @ mymaster 172.17.0.3 6379
- 重新启动原本的主实例
docker start master
docker exec -it master redis-cli
>info replication //该实例并没有变为主实例,而是作为slave1的从实例运行
完成
哨兵机制
哨兵进程主要负责三个任务
监控
周期性发送Ping命令检测主实例和从实例是否在线
哨兵检测从库,若从库响应超时则标为主观下线,因为从库的下线对集群影响不大
哨兵检测主库,若主库响应超时则标为客观下线,这个因为网络延迟等不可避免的原因可能被误判,所以为减少误判需要进行多人投票,对应该设置的2,表示要2台从库标记为客观下线
sentinel monitor mymaster 172.17.0.2 6379 2
选主
主库挂了按一定的流程选择新的主库
筛选之后按照一定的规则,逐个打分
- 筛选
保证从库仍在运行且之前的网络连接状态要好,具体表现为配置项down-after-milliseconds*10 - 进行三轮打分
1.优先级最高得分高
配置项slave-proprity,用户可以根据自己的主机内存给高低优先级
2.和旧主库同步率最高得分高
根据repl_backlog_buffer(增量复制的缓冲区)的slave_repl_offset来判断
3.ID号小得分高
redis启动时给的
- 通知
把新主库的连接信息发送给其他从库,让他们执行replicaof命令和新主库建立连接,同时把新主库的连接信息通知给客户端,让其把请求发送到新主库上
哨兵实例如何知道从库信息
由于Redis提供的发布/订阅机制(pub/sub),哨兵实例之间可以互相发现对方
哨兵实例只要和主库建立连接,就可以在主库上发布自己的连接信息(IP和端口),因此他们能获取彼此的IP地址和端口
同时,哨兵也会向主库发送info命令获取集群的主从列表信息,这样就可以和每个从库建立连接并持续监控
注意:如果假设上面的哨兵集群只有2个实例(2从),一个哨兵挂了,另一个想称为leader是不可能的,因为设置决定必须获得2票,而不是自己的一票
因此我们需要保证所有哨兵的实例配置都是一致的,尤其是主观下线的判断值down-after-milliseconds(减少下线的误判)
网友评论