前言:

主从切换技术的方法是:当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。

哨兵模式概述

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

Redis哨兵故障切花 redis哨兵故障转移不切换_Redis哨兵故障切花


这里的哨兵有两个作用

  • 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
  • 当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换主机。

然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

用文字描述一下故障切换(failover)的过程。假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover操作。切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。这样对于客户端而言,一切都是透明的

有关原理可以参考: redis中文文档参考

实验环境:

server1

172.25.75.1

master

server2

172.25.75.2

slave

server3

172.25.75.3

slave

一、配置redis一主多从环境

1、获得资源包,解压,安装(redis可以不用编译,直接make)

[root@server1 ~]# ls
redis-5.0.3.tar.gz
[root@server1 ~]# tar zxf redis-5.0.3.tar.gz 
[root@server1 ~]# ls
redis-5.0.3  redis-5.0.3.tar.gz
[root@server1 ~]# cd redis-5.0.3
[root@server1 redis-5.0.3]# ls
00-RELEASENOTES  CONTRIBUTING  deps     Makefile   README.md   runtest          runtest-sentinel  src    utils
BUGS             COPYING       INSTALL  MANIFESTO  redis.conf  runtest-cluster  sentinel.conf     tests

Redis哨兵故障切花 redis哨兵故障转移不切换_服务器_02

2、下载编译安装所需的依赖包

[root@server1 redis-5.0.3]# yum install gcc -y

3、编译安装

[root@server1 redis-5.0.3]# make
[root@server1 redis-5.0.3]# make install

Redis哨兵故障切花 redis哨兵故障转移不切换_Redis哨兵故障切花_03

4、server2、server3操作相同,此处将make好的目录发送过去,在执行make install

server1:

[root@server1 ~]# ls
redis-5.0.3  redis-5.0.3.tar.gz
[root@server1 ~]# scp -r redis-5.0.3 root@172.25.75.2:

server2、server3:

cd redis-5.0.3/

make install
cd src && make install
make[1]: Entering directory `/root/redis-5.0.3/src'

Hint: It's a good idea to run 'make test' ;)

    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
make[1]: Leaving directory `/root/redis-5.0.3/src'

Redis哨兵故障切花 redis哨兵故障转移不切换_Redis哨兵故障切花_04


Redis哨兵故障切花 redis哨兵故障转移不切换_Redis哨兵故障切花_05

5、在主redis上进行初始化,并且修改配置文件

[root@server1 ~]# cd redis-5.0.3/utils/
[root@server1 utils]# ls
build-static-symbols.tcl  generate-command-help.rb  install_server.sh  redis_init_script.tpl  whatisdoing.sh
cluster_fail_time.tcl     graphs                    lru                redis-sha1.rb
corrupt_rdb.c             hashtable                 redis-copy.rb      releasetools
create-cluster            hyperloglog               redis_init_script  speed-regression.tcl
[root@server1 utils]# ./install_server.sh 
Welcome to the redis service installer
This script will help you easily set up a running redis server

Please select the redis port for this instance: [6379] 
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] 
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] 
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] 
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server] 
Selected config:
Port           : 6379
Config file    : /etc/redis/6379.conf
Log file       : /var/log/redis_6379.log
Data dir       : /var/lib/redis/6379
Executable     : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!

Redis哨兵故障切花 redis哨兵故障转移不切换_Redis_06

查看端口号: 发现127.0.0.1:6379

[root@server1 utils]# netstat -antplu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      16809/redis-server  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      902/sshd            
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1520/master         
tcp        0      0 172.25.75.1:22          172.25.75.250:58266     ESTABLISHED 2109/sshd: root@pts 
tcp6       0      0 :::22                   :::*                    LISTEN      902/sshd            
tcp6       0      0 ::1:25                  :::*                    LISTEN      1520/master

修改配置文件:

[root@server1 utils]# vim /etc/redis/6379.conf 
  70 bind 0.0.0.0

Redis哨兵故障切花 redis哨兵故障转移不切换_Redis哨兵故障切花_07


设置端口绑定:

[root@server1 utils]# /etc/init.d/redis_6379 restart		#不要用systemctl(可能会没效果)
Stopping ...
Redis stopped
Starting Redis server...
[root@server1 utils]# netstat -antplu		#发现端口号修改了
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      16822/redis-server  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      902/sshd            
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1520/master         
tcp        0      0 127.0.0.1:6379          127.0.0.1:42572         TIME_WAIT   -                   
tcp        0      0 172.25.75.1:22          172.25.75.250:58266     ESTABLISHED 2109/sshd: root@pts 
tcp6       0      0 :::22                   :::*                    LISTEN      902/sshd            
tcp6       0      0 ::1:25                  :::*                    LISTEN      1520/master

Redis哨兵故障切花 redis哨兵故障转移不切换_Redis哨兵故障切花_08

6、在server2和server3的redis也进行初始化,修改配置文件

我们以servser2为例子:

[root@server2 redis-5.0.3]# cd utils/
[root@server2 utils]# ./install_server.sh
[root@server2 utils]# vim /etc/redis/6379.conf
  70 bind 0.0.0.0
[root@server2 utils]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...
[root@server2 utils]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      12481/redis-server  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      856/sshd            
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1168/master         
tcp6       0      0 :::22                   :::*                    LISTEN      856/sshd            
tcp6       0      0 ::1:25                  :::*                    LISTEN      1168/master

Redis哨兵故障切花 redis哨兵故障转移不切换_Redis哨兵故障切花_09

7、配置一主多从

server2-3:

[root@server2 utils]# vim /etc/redis/6379.conf 
1380 slaveof 172.25.75.1 6379
[root@server2 utils]# /etc/init.d/redis_6379 restart
Stopping ...
Redis stopped
Starting Redis server...

Redis哨兵故障切花 redis哨兵故障转移不切换_Redis哨兵故障切花_10


Redis哨兵故障切花 redis哨兵故障转移不切换_服务器_11

测试

server1:

[root@server1 utils]# redis-cli 
127.0.0.1:6379> info
# Replication
role:master	#自己为master
connected_slaves:2
slave0:ip=172.25.75.2,port=6379,state=online,offset=210,lag=0	#两个从属节点
slave1:ip=172.25.75.3,port=6379,state=online,offset=210,lag=0
master_replid:320e30394da07701e84575ddcf907b1a4bb989db
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:224
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:224
127.0.0.1:6379> set name zhao		#master拥有读写权限
OK
127.0.0.1:6379> get name
"zhao"

Redis哨兵故障切花 redis哨兵故障转移不切换_服务器_12


server2-3:

[root@server2 utils]# redis-cli 
127.0.0.1:6379> info
# Replication
role:slave
master_host:172.25.75.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:280
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:320e30394da07701e84575ddcf907b1a4bb989db
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:280
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:280

127.0.0.1:6379> get name		#slave节点只有可读权限
"zhao"
127.0.0.1:6379> set name liu
(error) READONLY You can't write against a read only replica.

Redis哨兵故障切花 redis哨兵故障转移不切换_服务器_13

二、redis哨兵机制-高可用

1、将哨兵配置文件复制到redis的配置目录下,修改哨兵配置文件。同时发送给其他slave节点。

server1:

[root@server1 redis-5.0.3]# pwd
/root/redis-5.0.3
[root@server1 redis-5.0.3]# cp sentinel.conf /etc/redis/
[root@server1 redis-5.0.3]# cd /etc/redis/
[root@server1 redis]# vim sentinel.conf
 17 protected-mode no		#关闭
  84 sentinel monitor mymaster 172.25.75.1 6379 2		#mymaster是名字, 2表示2个slave
  113 sentinel down-after-milliseconds mymaster 10000		#等待10s

发送哨兵配置文件给其他slave节点

[root@server1 redis]# scp sentinel.conf server2:/etc/redis/
sentinel.conf                                 100% 9710     9.5KB/s   00:00    
[root@server1 redis]# scp sentinel.conf server3:/etc/redis/
sentinel.conf                                 100% 9710     9.5KB/s   00:00

Redis哨兵故障切花 redis哨兵故障转移不切换_服务器_14

2、主从上都打开哨兵进程

[root@server1 redis]# redis-server /etc/redis/sentinel.conf --sentinel
[root@server2 ~]# redis-server /etc/redis/sentinel.conf --sentinel
[root@server3 ~]# redis-server /etc/redis/sentinel.conf --sentinel

master的结果:

Redis哨兵故障切花 redis哨兵故障转移不切换_服务器_15


可以看到信息,server1为master,server2-3都是slave节点。

3、测试

重新开启一个终端远程连接server1查看端口发现哨兵26379进程开启:

Redis哨兵故障切花 redis哨兵故障转移不切换_redis_16


进入redis数据库:

[root@server1 ~]# redis-cli 
127.0.0.1:6379> info	#查看状态信息,此时server1是master
# Replication
role:master
connected_slaves:2
slave0:ip=172.25.75.2,port=6379,state=online,offset=59072,lag=0
slave1:ip=172.25.75.3,port=6379,state=online,offset=59072,lag=0

查看26479端口:

[root@server1 ~]# redis-cli -p 26379
127.0.0.1:26379> info
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.25.75.1:6379,slaves=2,sentinels=3

Redis哨兵故障切花 redis哨兵故障转移不切换_redis_17


注意:此时显示主是server1,sentinels=3表示成功

测试:

将server1的redis-cli关闭

[root@server1 ~]# redis-cli 
127.0.0.1:6379> SHUTDOWN
not connected>

Redis哨兵故障切花 redis哨兵故障转移不切换_redis_18


此时redis会随机选择一个slave作master:

Redis哨兵故障切花 redis哨兵故障转移不切换_redis_19


我们可以看到此时哨兵为我们挑选了server3作为新的master!!!我们从server2上查看信息:

Redis哨兵故障切花 redis哨兵故障转移不切换_服务器_20


master已经更改为server3了!!!

我们在新的master上写入信息,再在server2上查看:

Redis哨兵故障切花 redis哨兵故障转移不切换_服务器_21


查看:

Redis哨兵故障切花 redis哨兵故障转移不切换_服务器_22