Redis Sentinel 介绍与部署
一、Sentinel介绍
主从复制的问题
Redis主从复制可将主节点数据同步给从节点,从节点此时有两个作用:
·一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。
·扩展主节点的读能力,分担主节点读压力。
但是问题来了:
·一旦主节点宕机,从节点晋升成主节点,同时需要修改应用方的主节点地址,还需要命令所有从节点去复制新的主节点,整个过程需要人工干预。
·主节点的写能力受到单机的限制。
·主节点的存储能力受到单机的限制。
第一个问题,我们接下来讲的Sentinel就可以解决。而后两个问题,Redis也给出了方案Redis Cluster。
Redis Sentinel的高可用
Redis Sentinel是一个分布式架构,包含若干个Sentinel节点和Redis数据节点,每个Sentinel节点会对数据节点和其余Sentinel节点进行监控,当发现节点不可达时,会对节点做下线标识。
如果被标识的是主节点,他还会选择和其他Sentinel节点进行“协商”,当大多数的Sentinel节点都认为主节点不可达时,他们会选举出一个Sentinel节点来完成自动故障转移工作,同时将这个变化通知给Redis应用方。
整个过程完全自动,不需要人工介入,所以可以很好解决Redis的高可用问题。
接下来就通过部署一个Redis Sentinel实例来了解整体框架。
二、部署
环境介绍
分别有3个Sentinel节点,1个主节点,2个从节点组成一个Redis Sentinel。
集群机器 redis服务 哨兵(sentinel) 节点描述虚拟机:172.16.86.79 安装redis服务,端口6379 安装sentinel服务,端口26379 主节点虚拟机:172.16.86.80 安装redis服务,端口6379 安装sentinel服务,端口26379 从节点虚拟机:172.16.86.81 安装redis服务, 端口6379 安装sentinel服务,端口26379 从节点
主节点(79)安装redis
1)安装路径
/app/redis
2)安装过程
上传文件redis-3.2.1.tar.gz到/app/tools-conf下
[root@DFJK-TEST-25 ~]# mkdir -p app/redis/[root@DFJK-TEST-25 ~]# cd app/tools-conf/[root@DFJK-TEST-25 tools-conf]# tar zxvf redis-3.2.1.tar.gz[root@DFJK-TEST-25 tools-conf]# cd redis-3.2.1[root@DFJK-TEST-25 redis-3.2.1]# make[root@DFJK-TEST-25 redis-3.2.1]# make PREFIX=/app/redis install
3)更改配置文件
[root@DFJK-TEST-25 ~]# mkdir -p etc/redis[root@DFJK-TEST-25 ~]# cd etc/red[root@DFJK-TEST-25 ~]# cd etc/redis/[root@DFJK-TEST-25 redis]# vi redis.conf[root@DFJK-TEST-25 redis]# cat redis.conf################################ GENERAL #####################################daemonize yespidfile "/var/run/redis.pid"port 6379tcp-backlog 511timeout 0tcp-keepalive 60loglevel noticelogfile "/app/redis/redis_log"databases 16################################ SNAPSHOTTING ################################save 600 5000stop-writes-on-bgsave-error nordbcompression nordbchecksum yesdbfilename "dump.rdb"dir "/app/redis/dump"################################# REPLICATION ################################## slaveofmasterauth "dfjk_qwe"slave-serve-stale-data yesslave-read-only norepl-diskless-sync norepl-diskless-sync-delay 5repl-ping-slave-period 10repl-disable-tcp-nodelay no# repl-backlog-size 1mb# repl-backlog-ttl 3600slave-priority 100# min-slaves-to-write 3# min-slaves-max-lag 10# min-slaves-max-lag is set to 10.################################## SECURITY ###################################requirepass "dfjk_qwe"################################### LIMITS ##################################### maxclients 10000maxmemory 5859375kb# maxmemory-policy noeviction# maxmemory-samples 5############################## APPEND ONLY MODE ###############################appendonly noappendfilename "appendonly.aof"# appendfsync alwaysappendfsync everysec# appendfsync nono-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mbaof-load-truncated yes################################ LUA SCRIPTING ###############################lua-time-limit 5000################################## SLOW LOG ###################################slowlog-log-slower-than 10000slowlog-max-len 128################################ LATENCY MONITOR ##############################latency-monitor-threshold 0############################# EVENT NOTIFICATION ##############################notify-keyspace-events ""############################### ADVANCED CONFIG ###############################hash-max-ziplist-entries 512hash-max-ziplist-value 64list-max-ziplist-entries 512list-max-ziplist-value 64set-max-intset-entries 512zset-max-ziplist-entries 128zset-max-ziplist-value 64hll-sparse-max-bytes 3000activerehashing yesclient-output-buffer-limit normal 0 0 0client-output-buffer-limit slave 256mb 64mb 60client-output-buffer-limit pubsub 32mb 8mb 60hz 150aof-rewrite-incremental-fsync yes# Generated by CONFIG REWRITE
4)编辑系统启动文件
[root@DFJK-TEST-25 redis]## vi etc/profile添加:export PATH="$PATH:/app/redis/bin"[root@DFJK-TEST-25 redis]# cat etc/init.d/redis#!/bin/sh#chkconfig: 2345 80 90# Simple Redis init.d script conceived to work on Linux systems# as it does use of the proc filesystem.PASSWD=dfjk_qweREDISPORT=6379EXEC=/app/redis/bin/redis-serverCLIEXEC=/app/redis/bin/redis-cliPIDFILE=/var/run/redis.pidCONF="/etc/redis/redis.conf"case "$1" instart)if [ -f $PIDFILE ]thenecho "$PIDFILE exists, process is already running or crashed"elseecho "Starting Redis server..."$EXEC $CONF &fi;;stop)if [ ! -f $PIDFILE ]thenecho "$PIDFILE does not exist, process is not running"elsePID=$(cat $PIDFILE)echo "Stopping ..."$CLIEXEC -p $REDISPORT -a $PASSWD shutdownwhile [ -x proc/${PID} ]doecho "Waiting for Redis to shutdown ..."sleep 1doneecho "Redis stopped"fi;;*)echo "Please use start or stop as first argument";;Esac
5)sentinel配置
cat /etc/redis/sentinel.conf# sentinel.confprotected-mode no #关闭保护模式daemonize yeslogfile "/app/redis/sentinel.log"port 26379#myid是自动生成(配置时不需要填写)sentinel myid 6b3609b66b93922a036927591eba3622f39a5f6c#自动生成sentinel monitor mymaster 172.16.86.79 6379 2#2表示在sentinel集群中只要有两个节点检测到redis主节点出故障就进行切换,单sentinel节点无效(自己测试发现的)sentinel down-after-milliseconds mymaster 5000#如果5s内mymaster无响应,则认为mymaster宕机了sentinel failover-timeout mymaster 15000#如果15秒后,mysater仍没活过来,则启动failoversentinel auth-pass mymaster dfjk_qwe#redis主节点密码dir "/app/redis/tmp"#指定工作目录# Generated by CONFIG REWRITEsentinel config-epoch mymaster 38sentinel leader-epoch mymaster 2134#以下是自动生成(配置时不需要填写)sentinel known-slave mymaster 172.16.86.81 6379sentinel known-slave mymaster 172.16.86.80 6379sentinel known-sentinel mymaster 172.16.86.80 26379 4a1c268f5be39d175d78b583cbfaaae7cdcc71d5sentinel known-sentinel mymaster 172.16.86.81 26379 b2022311b7e37e3fac9d404a3918b08d1bbea140sentinel current-epoch 2134
从节点80安装
1)安装路径
/app/redis
2)安装过程
上传文件redis-3.2.1.tar.gz到/app/tools-conf下
[root@DFJK-TEST-26 ~]# mkdir -p app/redis/[root@DFJK-TEST-26 ~]# cd app/tools-conf/[root@DFJK-TEST-26 tools-conf]# tar zxvf redis-3.2.1.tar.gz[root@DFJK-TEST-26 tools-conf]# cd redis-3.2.1[root@DFJK-TEST-26 redis-3.2.1]# make[root@DFJK-TEST-26 redis-3.2.1]# make PREFIX=/app/redis install
3)更改配置文件
[root@DFJK-TEST-26 ~]# mkdir -p etc/redis[root@DFJK-TEST-26 ~]# cd etc/redis/[root@DFJK-TEST-26 redis]# vi redis.conf################################ GENERAL #####################################daemonize yespidfile "/var/run/redis.pid"port 6379tcp-backlog 511timeout 0tcp-keepalive 60loglevel noticelogfile "/app/redis/redis_log"databases 16################################ SNAPSHOTTING ################################save 600 5000stop-writes-on-bgsave-error nordbcompression nordbchecksum yesdbfilename "dump.rdb"dir "/app/redis/dump"################################# REPLICATION ################################## slaveof <masterip> <masterport>masterauth "dfjk_qwe"slave-serve-stale-data yesslave-read-only norepl-diskless-sync norepl-diskless-sync-delay 5repl-ping-slave-period 10repl-disable-tcp-nodelay no# repl-backlog-size 1mb# repl-backlog-ttl 3600slave-priority 100# min-slaves-to-write 3# min-slaves-max-lag 10# min-slaves-max-lag is set to 10.################################## SECURITY ###################################requirepass "dfjk_qwe"################################### LIMITS ##################################### maxclients 10000maxmemory 5859375kb# maxmemory-policy noeviction# maxmemory-samples 5############################## APPEND ONLY MODE ###############################appendonly noappendfilename "appendonly.aof"# appendfsync alwaysappendfsync everysec# appendfsync nono-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mbaof-load-truncated yes################################ LUA SCRIPTING ###############################lua-time-limit 5000################################## SLOW LOG ###################################slowlog-log-slower-than 10000slowlog-max-len 128################################ LATENCY MONITOR ##############################latency-monitor-threshold 0############################# EVENT NOTIFICATION ##############################notify-keyspace-events ""############################### ADVANCED CONFIG ###############################hash-max-ziplist-entries 512hash-max-ziplist-value 64list-max-ziplist-entries 512list-max-ziplist-value 64set-max-intset-entries 512zset-max-ziplist-entries 128zset-max-ziplist-value 64hll-sparse-max-bytes 3000activerehashing yesclient-output-buffer-limit normal 0 0 0client-output-buffer-limit slave 256mb 64mb 60client-output-buffer-limit pubsub 32mb 8mb 60hz 150aof-rewrite-incremental-fsync yes# Generated by CONFIG REWRITEslaveof 172.16.86.79 6379
4)编辑系统启动文件
[root@DFJK-TEST-26 redis]# vi etc/profile添加:export PATH="$PATH:/app/redis/bin"[root@DFJK-TEST-26 redis]# . etc/profile[root@DFJK-TEST-26 redis]# cat etc/init.d/redis#!/bin/sh#chkconfig: 2345 80 90# Simple Redis init.d script conceived to work on Linux systems# as it does use of the proc filesystem.PASSWD=dfjk_qweREDISPORT=6379EXEC=/app/redis/bin/redis-serverCLIEXEC=/app/redis/bin/redis-cliPIDFILE=/var/run/redis.pidCONF="/etc/redis/redis.conf"case "$1" instart)if [ -f $PIDFILE ]thenecho "$PIDFILE exists, process is already running or crashed"elseecho "Starting Redis server..."$EXEC $CONF &fi;;stop)if [ ! -f $PIDFILE ]thenecho "$PIDFILE does not exist, process is not running"elsePID=$(cat $PIDFILE)echo "Stopping ..."$CLIEXEC -p $REDISPORT -a $PASSWD shutdownwhile [ -x proc/${PID} ]doecho "Waiting for Redis to shutdown ..."sleep 1doneecho "Redis stopped"fi;;*)echo "Please use start or stop as first argument";;Esac
5)sentinel配置
[root@DFJK-TEST-26 ~]# vi etc/redis/sentinel.conf# sentinel.confprotected-mode no #关闭保护模式daemonize yeslogfile "/app/redis/sentinel.log"port 26379#myid是自动生成(配置时不需要填写)sentinel myid 4a1c268f5be39d175d78b583cbfaaae7cdcc71d5sentinel monitor mymaster 172.16.86.79 6379 2#2表示在sentinel集群中只要有两个节点检测到redis主节点出故障就进行切换,单sentinel节点无效(自己测试发现的)sentinel down-after-milliseconds mymaster 5000#如果5s内mymaster无响应,则认为mymaster宕机了#redis主节点密码dir "/app/redis/tmp"#指定工作目录# Generated by CONFIG REWRITEsentinel failover-timeout mymaster 15000#如果15秒后,mysater仍没活过来,则启动failoversentinel auth-pass mymaster dfjk_qwesentinel config-epoch mymaster 38sentinel leader-epoch mymaster 38#以下是自动生成(配置时不需要填写)sentinel known-slave mymaster 172.16.86.81 6379sentinel known-slave mymaster 172.16.86.80 6379sentinel known-sentinel mymaster 172.16.86.81 26379 b2022311b7e37e3fac9d404a3918b08d1bbea140sentinel known-sentinel mymaster 172.16.86.79 26379 6b3609b66b93922a036927591eba3622f39a5f6csentinel current-epoch 2134
从节点81安装
1)安装路径
/app/redis
2)安装过程
上传文件redis-3.2.1.tar.gz到/app/tools-conf下
[root@DFJK-TEST-27 ~]# mkdir -p app/redis/[root@DFJK-TEST-27 ~]# cd /app/tools-conf/[root@DFJK-TEST-27 tools-conf]# tar zxvf redis-3.2.1.tar.gz[root@DFJK-TEST-27 tools-conf]# cd redis-3.2.1[root@DFJK-TEST-27 redis-3.2.1]# make[root@DFJK-TEST-27 redis-3.2.1]# make PREFIX=/app/redis install
3)更改配置文件
[root@DFJK-TEST-27 ~]# mkdir -p etc/redis[root@DFJK-TEST-27 ~]# cd /etc/redis/[root@DFJK-TEST-27 redis]# vi redis.conf################################ GENERAL #####################################daemonize yespidfile "/var/run/redis.pid"port 6379tcp-backlog 511timeout 0tcp-keepalive 60loglevel noticelogfile "/app/redis/redis_log"databases 16################################ SNAPSHOTTING ################################save 600 5000stop-writes-on-bgsave-error nordbcompression nordbchecksum yesdbfilename "dump.rdb"dir "/app/redis/dump"################################# REPLICATION ################################## slaveofmasterauth "dfjk_qwe"slave-serve-stale-data yesslave-read-only norepl-diskless-sync norepl-diskless-sync-delay 5repl-ping-slave-period 10repl-disable-tcp-nodelay no# repl-backlog-size 1mb# repl-backlog-ttl 3600slave-priority 100# min-slaves-to-write 3# min-slaves-max-lag 10# min-slaves-max-lag is set to 10.################################## SECURITY ###################################requirepass "dfjk_qwe"################################### LIMITS ##################################### maxclients 10000maxmemory 5859375kb# maxmemory-policy noeviction# maxmemory-samples 5############################## APPEND ONLY MODE ###############################appendonly noappendfilename "appendonly.aof"# appendfsync alwaysappendfsync everysec# appendfsync nono-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mbaof-load-truncated yes################################ LUA SCRIPTING ###############################lua-time-limit 5000################################## SLOW LOG ###################################slowlog-log-slower-than 10000slowlog-max-len 128################################ LATENCY MONITOR ##############################latency-monitor-threshold 0############################# EVENT NOTIFICATION ##############################notify-keyspace-events ""############################### ADVANCED CONFIG ###############################hash-max-ziplist-entries 512hash-max-ziplist-value 64list-max-ziplist-entries 512list-max-ziplist-value 64set-max-intset-entries 512zset-max-ziplist-entries 128zset-max-ziplist-value 64hll-sparse-max-bytes 3000activerehashing yesclient-output-buffer-limit normal 0 0 0client-output-buffer-limit slave 256mb 64mb 60client-output-buffer-limit pubsub 32mb 8mb 60hz 150aof-rewrite-incremental-fsync yes# Generated by CONFIG REWRITEslaveof 172.16.86.79 6379
4)编辑系统启动文件
[root@DFJK-TEST-27 redis]# vi etc/profile添加:export PATH="$PATH:/app/redis/bin"[root@DFJK-TEST-27 redis]# . etc/profile[root@DFJK-TEST-27 redis]# cat etc/init.d/redis#!/bin/sh#chkconfig: 2345 80 90# Simple Redis init.d script conceived to work on Linux systems# as it does use of the proc filesystem.PASSWD=dfjk_qweREDISPORT=6379EXEC=/app/redis/bin/redis-serverCLIEXEC=/app/redis/bin/redis-cliPIDFILE=/var/run/redis.pidCONF="/etc/redis/redis.conf"case "$1" instart)if [ -f $PIDFILE ]thenecho "$PIDFILE exists, process is already running or crashed"elseecho "Starting Redis server..."$EXEC $CONF &fi;;stop)if [ ! -f $PIDFILE ]thenecho "$PIDFILE does not exist, process is not running"elsePID=$(cat $PIDFILE)echo "Stopping ..."$CLIEXEC -p $REDISPORT -a $PASSWD shutdownwhile [ -x proc/${PID} ]doecho "Waiting for Redis to shutdown ..."sleep 1doneecho "Redis stopped"fi;;*)echo "Please use start or stop as first argument";;esac
5)sentinel配置
[root@DFJK-TEST-26 ~]# vi etc/redis/sentinel.confcat /etc/redis/sentinel.conf# sentinel.confprotected-mode no #关闭保护模式daemonize yeslogfile "/app/redis/sentinel.log"port 26379sentinel monitor mymaster 172.16.86.79 6379 2#2表示在sentinel集群中只要有两个节点检测到redis主节点出故障就进行切换,单sentinel节点无效(自己测试发现的)sentinel down-after-milliseconds mymaster 5000#如果5s内mymaster无响应,则认为mymaster宕机了sentinel failover-timeout mymaster 15000#如果15秒后,mysater仍没活过来,则启动failoversentinel auth-pass mymaster dfjk_qwe#redis主节点密码dir "/app/redis/tmp"#指定工作目录# Generated by CONFIG REWRITEsentinel config-epoch mymaster 38sentinel leader-epoch mymaster 38sentinel known-slave mymaster 172.16.86.80 6379sentinel known-slave mymaster 172.16.86.81 6379sentinel known-sentinel mymaster 172.16.86.80 26379 4a1c268f5be39d175d78b583cbfaaae7cdcc71d5sentinel known-sentinel mymaster 172.16.86.79 26379 6b3609b66b93922a036927591eba3622f39a5f6csentinel current-epoch 2134
启动并检测
1)主redis(79)启动
[root@DFJK-TEST-25 ~]# chmod +x etc/init.d/redis[root@DFJK-TEST-25 ~]# mkdir -p app/redis/dump[root@DFJK-TEST-25 redis]# mkdir -p app/redis/tmp[root@DFJK-TEST-25 redis]# service redis startStarting Redis server...[root@DFJK-TEST-25 redis]# ps -ef |grep -v grep |grep redisroot 27816 1 0 09:53 ? 00:00:00 app/redis/bin/redis-server *:6379
2)主redis(79)启动sentinel
[root@DFJK-TEST-25 redis]# redis-sentinel etc/redis/sentinel.conf[root@DFJK-TEST-25 redis]# ps -ef |grep -v grep |grep sentinelroot 27823 1 0 09:53 ? 00:00:00 redis-sentinel *:26379 [sentinel]
3)从redis(80)启动
[root@DFJK-TEST-26 ~]# chmod +x etc/init.d/redis[root@DFJK-TEST-26 ~]# mkdir -p app/redis/dump[root@DFJK-TEST-26 redis]# mkdir -p app/redis/tmp[root@DFJK-TEST-26 redis]# service redis startStarting Redis server...[root@DFJK-TEST-26 redis]# ps -ef |grep -v grep |grep redisroot 20247 1 0 09:54 ? 00:00:00 app/redis/bin/redis-server *:6379
4)从redis(80)启动sentinel
[root@DFJK-TEST-26 redis]# redis-sentinel etc/redis/sentinel.conf[root@DFJK-TEST-26 redis]# ps -ef |grep -v grep |grep sentinelroot 20261 1 0 09:55 ? 00:00:00 redis-sentinel *:26379 [sentinel]
5)从redis(81)启动
[root@DFJK-TEST-27 ~]# chmod +x etc/init.d/redis[root@DFJK-TEST-27 ~]# mkdir -p app/redis/dump[root@DFJK-TEST-27 redis]# mkdir -p app/redis/tmp[root@DFJK-TEST-27 redis]# service redis startStarting Redis server...[root@DFJK-TEST-27 ~]# ps -ef |grep -v grep |grep redisroot 10869 1 0 09:55 ? 00:00:00 /app/redis/bin/redis-server *:6379
6)从redis(81)启动sentinel
[root@DFJK-TEST-27 ~]# redis-sentinel /etc/redis/sentinel.conf[root@DFJK-TEST-27 ~]# ps -ef |grep -v grep |grep sentinelroot 10882 1 0 09:56 ? 00:00:00 redis-sentinel *:26379 [sentinel]
7)ping命令查看是否启动
[root@DFJK-TEST-25 ~]# redis-cli -h 172.16.86.80 -p 6379 -a "dfjk_qwe" pingPONG[root@DFJK-TEST-25 ~]# redis-cli -h 172.16.86.81 -p 6379 -a "dfjk_qwe" pingPONG[root@DFJK-TEST-25 ~]# redis-cli -h 172.16.86.79 -p 6379 -a "dfjk_qwe" pingPONG
确定主从关系
部署三个Sentinel节点之后,真个拓扑结构如图所示:

验证复制
1)主节点视角
[root@DFJK-TEST-25 ~]# redis-cli -h 172.16.86.79 -p 6379 -a "dfjk_qwe" INFO replication# Replicationrole:masterconnected_slaves:2slave0:ip=172.16.86.80,port=6379,state=online,offset=57709,lag=1slave1:ip=172.16.86.81,port=6379,state=online,offset=57995,lag=0master_repl_offset:58138repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:58137
2)从节点1视角
[root@DFJK-TEST-26 ~]# redis-cli -h 172.16.86.80 -p 6379 -a "dfjk_qwe" INFO replication# Replicationrole:slavemaster_host:172.16.86.79master_port:6379master_link_status:upmaster_last_io_seconds_ago:2master_sync_in_progress:0slave_repl_offset:62027slave_priority:100slave_read_only:0connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0
3)从节点2视角
[root@DFJK-TEST-27 ~]# redis-cli -h 172.16.86.81 -p 6379 -a "dfjk_qwe" INFO replication# Replicationrole:slavemaster_host:172.16.86.79master_port:6379master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:68075slave_priority:100slave_read_only:0connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0
主写入:
[root@DFJK-TEST-25 ~]# redis-cli -h 172.16.86.79 -p 6379 -a "dfjk_qwe"
172.16.86.79:6379> set name xiaoming
OK
172.16.86.79:6379> get name
"xiaoming"
从查看:
[root@DFJK-TEST-26 ~]# redis-cli -h 172.16.86.80 -p 6379 -a "dfjk_qwe"
172.16.86.80:6379> get name
"xiaoming"
[root@DFJK-TEST-27 ~]# redis-cli -h 172.16.86.81 -p 6379 -a "dfjk_qwe"
172.16.86.81:6379> get name
"xiaoming"
故障验证
故障转移实验
主停止redis:
[root@DFJK-TEST-25 ~]# service redis stop
主sentinel日志:
27823:X 24 May 10:07:17.912 # +sdown master mymaster 172.16.86.79 637927823:X 24 May 10:07:17.912 # +odown master mymaster 172.16.86.79 6379 #quorum 1/127823:X 24 May 10:07:17.912 # +new-epoch 213527823:X 24 May 10:07:17.912 # +try-failover master mymaster 172.16.86.79 637927823:X 24 May 10:07:17.913 # +vote-for-leader 6b3609b66b93922a036927591eba3622f39a5f6c 213527823:X 24 May 10:07:28.713 # -failover-abort-not-elected master mymaster 172.16.86.79 637927823:X 24 May 10:07:28.771 # Next failover delay: I will not start a failover before Thu May 24 10:07:48 201827823:X 24 May 10:07:48.750 # +new-epoch 213627823:X 24 May 10:07:48.750 # +try-failover master mymaster 172.16.86.79 637927823:X 24 May 10:07:48.751 # +vote-for-leader 6b3609b66b93922a036927591eba3622f39a5f6c 213627823:X 24 May 10:07:59.020 # -failover-abort-not-elected master mymaster 172.16.86.79 637927823:X 24 May 10:07:59.075 # Next failover delay: I will not start a failover before Thu May 24 10:08:18 201827823:X 24 May 10:08:18.996 # +new-epoch 213727823:X 24 May 10:08:18.996 # +try-failover master mymaster 172.16.86.79 637927823:X 24 May 10:08:18.998 # +vote-for-leader 6b3609b66b93922a036927591eba3622f39a5f6c 213727823:X 24 May 10:08:29.936 # -failover-abort-not-elected master mymaster 172.16.86.79 637927823:X 24 May 10:08:29.994 # Next failover delay: I will not start a failover before Thu May 24 10:08:49 2018
从1的sentinel日志:
20261:X 24 May 10:07:17.938 # +sdown master mymaster 172.16.86.79 637920261:X 24 May 10:07:19.079 # +new-epoch 213520261:X 24 May 10:07:50.122 # +new-epoch 213620261:X 24 May 10:08:19.166 # +new-epoch 213720261:X 24 May 10:08:50.772 # +new-epoch 2138
从2的sentinel日志:
10882:X 24 May 10:07:17.990 # +sdown master mymaster 172.16.86.79 637910882:X 24 May 10:07:19.078 # +new-epoch 213510882:X 24 May 10:07:50.121 # +new-epoch 213610882:X 24 May 10:08:19.165 # +new-epoch 213710882:X 24 May 10:08:50.777 # +new-epoch 2138
此时,Redis Sentinel
对主节点进行客观下线(Objectively Down, 简称 ODOWN)的判断,确认主节点不可达,则通知从节点中止复制主节点的操作。

当主节点下线时长超过配置的下线时长5000毫秒
,Redis Sentinel
执行故障转移操作。
查看一下Sentinel节点监控的主节点信息:
[root@DFJK-TEST-25 ~]# redis-cli -h 172.16.86.79 -p 26379172.16.86.79:26379> sentinel masters1) 1) "name"2) "mymaster"3) "ip"4) "172.16.86.80"5) "port"6) "6379"7) "runid"8) "1ece1ee74e6a172c4522a34a2de0df8c94f24fed"9) "flags"10) "master"11) "link-pending-commands"12) "0"13) "link-refcount"14) "1"15) "last-ping-sent"16) "0"17) "last-ok-ping-reply"18) "231"19) "last-ping-reply"20) "231"21) "down-after-milliseconds"22) "5000"23) "info-refresh"24) "5219"25) "role-reported"26) "master"27) "role-reported-time"28) "35728"29) "config-epoch"30) "2158"31) "num-slaves"32) "2"33) "num-other-sentinels"34) "2"35) "quorum"36) "1"37) "failover-timeout"38) "15000"39) "parallel-syncs"40) "1"
看一下Sentinel节点监控的从节点信息:
172.16.86.79:26379> sentinel slaves mymaster1) 1) "name"2) "172.16.86.79:6379"3) "ip"4) "172.16.86.79"5) "port"6) "6379"7) "runid"8) ""9) "flags"10) "s_down,slave,disconnected" //端口79:6379的原主节点已经断开了连接11) "link-pending-commands"12) "2"13) "link-refcount"14) "1"15) "last-ping-sent"16) "227506"17) "last-ok-ping-reply"18) "227506"19) "last-ping-reply"20) "227506"21) "s-down-time"22) "222473"23) "down-after-milliseconds"24) "5000"25) "info-refresh"26) "1527129371700"27) "role-reported"28) "slave"29) "role-reported-time"30) "227506"31) "master-link-down-time"32) "0"33) "master-link-status"34) "err"35) "master-host"36) "?"37) "master-port"38) "0"39) "slave-priority"40) "100"41) "slave-repl-offset"42) "0"2) 1) "name"2) "172.16.86.81:6379"3) "ip"4) "172.16.86.81"5) "port"6) "6379"7) "runid"8) "b8dd9e7be4c1ea13e15f19f50b4a81647568b571"9) "flags"10) "slave"11) "link-pending-commands"12) "0"13) "link-refcount"14) "1"15) "last-ping-sent"16) "0"17) "last-ok-ping-reply"18) "338"19) "last-ping-reply"20) "338"21) "down-after-milliseconds"22) "5000"23) "info-refresh"24) "6713"25) "role-reported"26) "slave"27) "role-reported-time"28) "227506"29) "master-link-down-time"30) "0"31) "master-link-status"32) "ok"33) "master-host"34) "172.16.86.80"35) "master-port"36) "6379"37) "slave-priority"38) "100"39) "slave-repl-offset"40) "46732"
由以上信息可得,端口为80
的Redis数据节点成为新的主节点,端口为79
的旧主节点断开连接。如图所示:

重启79
的数据节点:
[root@DFJK-TEST-25 ~]# service redis startStarting Redis server...
查看下变化:
172.16.86.79:26379> sentinel slaves mymaster1) 1) "name"2) "172.16.86.79:6379" //79的节点重启后,变成了"活"的从节点3) "ip"4) "172.16.86.79"5) "port"6) "6379"7) "runid"8) "30876d99252c019af65ba40de62c42c5bc39d0dd"9) "flags"10) "slave"11) "link-pending-commands"12) "0"13) "link-refcount"14) "1"15) "last-ping-sent"16) "0"17) "last-ok-ping-reply"18) "605"19) "last-ping-reply"20) "605"21) "down-after-milliseconds"22) "5000"23) "info-refresh"24) "7726"25) "role-reported"26) "slave"27) "role-reported-time"28) "37834"29) "master-link-down-time"30) "0"31) "master-link-status"32) "ok"33) "master-host"34) "172.16.86.80"35) "master-port"36) "6379"37) "slave-priority"38) "100"39) "slave-repl-offset"40) "112149"2) 1) "name"2) "172.16.86.81:6379" //81的节点无变化,还是从节点3) "ip"4) "172.16.86.81"5) "port"6) "6379"7) "runid"8) "b8dd9e7be4c1ea13e15f19f50b4a81647568b571"9) "flags"10) "slave"11) "link-pending-commands"12) "0"13) "link-refcount"14) "1"15) "last-ping-sent"16) "0"17) "last-ok-ping-reply"18) "606"19) "last-ping-reply"20) "606"21) "down-after-milliseconds"22) "5000"23) "info-refresh"24) "3912"25) "role-reported"26) "slave"27) "role-reported-time"28) "536124"29) "master-link-down-time"30) "0"31) "master-link-status"32) "ok"33) "master-host"34) "172.16.86.80"35) "master-port"36) "6379"37) "slave-priority"38) "100"39) "slave-repl-offset"40) "113033"
79被降为80的从节点:
[root@DFJK-TEST-25 ~]# redis-cli -h 172.16.86.79 -p 6379 -a "dfjk_qwe" INFO replication# Replicationrole:slavemaster_host:172.16.86.80master_port:6379master_link_status:upmaster_last_io_seconds_ago:2master_sync_in_progress:0slave_repl_offset:133604slave_priority:100slave_read_only:0connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0[root@DFJK-TEST-25 ~]# redis-cli -h 172.16.86.80 -p 6379 -a "dfjk_qwe" INFO replication# Replicationrole:masterconnected_slaves:2slave0:ip=172.16.86.81,port=6379,state=online,offset=151565,lag=0slave1:ip=172.16.86.79,port=6379,state=online,offset=151710,lag=0master_repl_offset:152000repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:151999[root@DFJK-TEST-25 ~]# redis-cli -h 172.16.86.81 -p 6379 -a "dfjk_qwe" INFO replication# Replicationrole:slavemaster_host:172.16.86.80master_port:6379master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:152870slave_priority:100slave_read_only:0connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0

从上面的逻辑架构和故障转移试验中,可以看出Redis Sentinel的以下几个功能。
·监控:Sentinel节点会定期检测Redis数据节点和其余Sentinel节点是否可达。
·通知:Sentinel节点会将故障转移通知给应用方。
·主节点故障转移:实现从节点晋升为主节点并维护后续正确的主从关系。
·配置提供者:在Redis Sentinel结构中,客户端在初始化的时候连接的是Sentinel节点集合,从中获取主节点信息。
Sentinel配置说明
·sentinel monitor mymaster 127.0.0.1 6379 2
·当前Sentinel节点监控 127.0.0.1:6379 这个主节点
·2代表判断主节点失败至少需要2个Sentinel节点节点同意
·mymaster是主节点的别名
·sentinel down-after-milliseconds mymaster 30000
·每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒且没有回复,则判定不可达
·sentinel parallel-syncs mymaster 1
·当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1。
·sentinel failover-timeout mymaster 180000
·故障转移超时时间为180000
·sentinel auth-pass \ \
·如果Sentinel
监控的主节点配置了密码,可以通过sentinel auth-pass
配置通过添加主节点的密码,防止Sentinel
节点无法对主节点进行监控。
·例如:sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
·sentinel notification-script \ \
·在故障转移期间,当一些警告级别的Sentinel
事件发生(指重要事件,如主观下线,客观下线等)时,会触发对应路径的脚本,想脚本发送相应的事件参数。
·例如:sentinel notification-script mymaster /var/redis/notify.sh
·sentinel client-reconfig-script \ \
·在故障转移结束后,触发应对路径的脚本,并向脚本发送故障转移结果的参数。
·例如:sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
。




