redis哨兵高可用
1.redis-sentinel
Redis-Sentinel是redis官方推荐的高可用性解决方案,
当用redis作master-slave的高可用时,如果master本身宕机,redis本身或者客户端都没有实现主从切换的功能。
而redis-sentinel就是一个独立运行的进程,用于监控多个master-slave集群,
自动发现master宕机,进行自动切换slave > master。
2.redis-sentinel功能
1.不时的监控redis是否良好运行,如果节点不可达就会对节点进行下线标识
2.如果被标识的是主节点,sentinel就会和其他的sentinel节点“协商”,如果其他节点也人为主节点不可达,就会选举一个sentinel节点来完成自动故障转义
3.在master-slave进行切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换
3.sentinel的工作方式
每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令
如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线
在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。
主观下线和客观下线
主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover.
SDOWN适合于Master和Slave,只要一个 Sentinel 发现Master进入了ODOWN, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对下线的主服务器执行自动故障迁移操作。
ODOWN只适用于Master,对于Slave的 Redis 实例,Sentinel 在将它们判断为下线前不需要进行协商, 所以Slave的 Sentinel 永远不会达到ODOWN。
4.redis主从复制背景
Redis主从复制可将主节点数据同步给从节点,从节点此时有两个作用:
1.一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。
2.扩展主节点的读能力,分担主节点读压力。
但是问题是:
一旦主节点宕机,从节点上位,那么需要人为修改所有应用方的主节点地址(改为新的master地址),还需要命令所有从节点复制新的主节点
那么这个问题,redis-sentinel就可以解决了
5.主从复制架构
6.redis Sentinel架构
7.代码实现
1.环境准备
#三个redis数据实例,配置好 1主2从
#创建文件夹
[root@xujunk data]#mkdir sbredis
[root@xujunk data]#cd sbredis
#创建3个redis配置
[root@xujunk sbredis]#vim 6379.conf
[root@xujunk sbredis]#sed "s/6379/6380/g" 6379.conf > 6380.conf
[root@xujunk sbredis]#sed "s/6379/6381/g" 6379.conf > 6381.conf
"""
6379.conf
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
dir "/var/redis/data/"
6380.conf
port 6380
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
dir "/var/redis/data/"
slaveof 127.0.0.1 6379
6381.conf
port 6381
daemonize yes
logfile "6381.log"
dbfilename "dump-6381.rdb"
dir "/var/redis/data/"
slaveof 127.0.0.1 6379
"""
#配置从属关系
[root@xujunk sbredis]#echo "slaveof 127.0.0.1 6379" >> 6380.conf
[root@xujunk sbredis]#echo "slaveof 127.0.0.1 6379" >> 6381.conf
#创建文件用于存储数据和日志
[root@xujunk sbredis]#mkdir -p /var/redis/data/
#启动redis
[root@xujunk sbredis]#redis-server 6379.conf
[root@xujunk sbredis]#redis-server 6380.conf
[root@xujunk sbredis]#redis-server 6381.conf
[root@xujunk sbredis]#!ps
"""
ps -ef |grep redis
root 33158 1 0 21:15 ? 00:00:00 redis-server *:6379
root 33167 1 0 21:15 ? 00:00:00 redis-server *:6380
root 33175 1 1 21:15 ? 00:00:00 redis-server *:6381
root 33186 26372 0 21:15 pts/1 00:00:00 grep --color=auto redis
"""
#三个redis哨兵进程,指定好,检测着谁
#也是准备3个配置文件
sentinel-26379.conf
sentinel-26380.conf
sentinel-26381.conf
[root@xujunk sbredis]#touch sentinel-26379.conf
[root@xujunk sbredis]#vim sentinel-26379.conf
"""
port 26379
dir /var/redis/data/
logfile "26379.log"
sentinel monitor s21ms 127.0.0.1 6379 2
sentinel down-after-milliseconds s21ms 20000
sentinel parallel-syncs s21ms 1
sentinel failover-timeout s21ms 180000
daemonize yes
"""
#分别生成 sentinel-26380.conf sentinel-26381.conf
[root@xujunk sbredis]#sed "s/26379/26380/g" sentinel-26379.conf > sentinel-26380.conf
[root@xujunk sbredis]#sed "s/26379/26381/g" sentinel-26379.conf > sentinel-26381.conf
2.代码验证
#分别启动 三个redis数据库, 以及三个 哨兵进程 ,注意 ,哨兵第一次启动后,会修改配置文件,如果错了,得删除配置文件,重新写
1.启动哨兵
[root@xujunk sbredis]#redis-sentinel sentinel-26379.conf
[root@xujunk sbredis]#redis-sentinel sentinel-26380.conf
[root@xujunk sbredis]#redis-sentinel sentinel-26381.conf
2.查看后台哨兵,redis运行状态:
[root@xujunk sbredis]#!ps
"""
ps -ef |grep redis
root 33158 1 0 21:15 ? 00:00:00 redis-server *:6379
root 33167 1 0 21:15 ? 00:00:00 redis-server *:6380
root 33175 1 0 21:15 ? 00:00:00 redis-server *:6381
root 33853 1 0 21:24 ? 00:00:00 redis-sentinel *:26379 [sentinel]
root 33870 1 0 21:24 ? 00:00:00 redis-sentinel *:26380 [sentinel]
root 33877 1 1 21:24 ? 00:00:00 redis-sentinel *:26381 [sentinel]
"""
#运行状态正常
3.验证哨兵是否正常:
[root@xujunk sbredis]#redis-cli -p 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=s21ms,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3
"""
#name=s21ms,主节点address=127.0.0.1:6379 从节点2个 哨兵3个
3.干掉主库(主节点) ,检查主从切换状态
[root@xujunk sbredis]#kill -9 33158
4.查看从库(从节点)6380,6381 :
[root@xujunk sbredis]#redis-cli -p 6380 info replication
"""
# Replication
role:master #主节点
connected_slaves:1
slave0:ip=127.0.0.1,port=6381,state=online,offset=85816,lag=0
master_replid:9450087193f724b8538d25eef9336803ce96e71b
master_replid2:d43267907dd90579d5c9ef10af38464e49f23ba2
master_repl_offset:85816
second_repl_offset:84624
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:85816
"""
[root@xujunk sbredis]#redis-cli -p 6381 info replication
"""
# Replication
role:slave #从节点
master_host:127.0.0.1
master_port:6380 #归属6380端口
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:87130
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:9450087193f724b8538d25eef9336803ce96e71b
master_replid2:d43267907dd90579d5c9ef10af38464e49f23ba2
master_repl_offset:87130
second_repl_offset:84624
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:87130
"""
#可以看出6380端口切换成主库(主节点),6381端口切换成6380端口的从节点
3.哨兵配置内容介绍:
port 26379
dir /var/redis/data/
logfile "26379.log"
// 当前Sentinel节点监控 192.168.182.130:6379 这个主节点
// 2代表判断主节点失败至少需要2个Sentinel节点节点同意
// mymaster是主节点的别名
sentinel monitor s21ms 0.0.0.0 6379 2
//每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒30s且没有回复,则判定不可达
sentinel down-after-milliseconds s21ms 20000
//当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,
原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel parallel-syncs mymaster 1
//故障转移超时时间为180000毫秒
sentinel failover-timeout mymaster 180000