1. 环境及ip角色说明:
这里使用三台服务器,每台服务器上开启一个redis-server和redis-sentinel服务,
redis-server端口为8000,redis-sentinel的端口为6800,修改默认端口是安全的第一步
redis-server:
10.10.10.63:8000(主)
10.10.10.64:8000(从)
10.10.10.65:8000(从)
redis-sentinel:
10.10.10.63:6800
10.10.10.64:6800
10.10.10.65:6800
VIP:10.10.10.100
2. 配置redis-server
yum -y install redis #每台服务器都要安装
cp /etc/redis.conf{,.bak} && cp /etc/redis-sentinel.conf{,.bak} #先备份配置文件
修改主redis-server配置文件内容如下:
vim /etc/redis.conf
port 8000 #端口
daemonize yes #开启后台守护进程
bind 0.0.0.0 #绑定地址,默认是127.0.0.1,0.0.0.0表示绑定所有地址
pidfile "/var/run/redis-8000.pid"
logfile "/var/log/redis/redis-8000.log"
protected-mode no #关闭保护模式
修改从redis-server配置文件内容如下:
vim /etc/redis.conf
port 8000
daemonize yes
bind 0.0.0.0
protected-mode no
pidfile "/var/run/redis-8000.pid"
logfile "/var/log/redis/redis-8000.log"
slaveof 10.10.10.63 8000#指定主服务器ip和端口
启动redis-server,指定配置文件位置(主从服务器都要启动)
redis-server /etc/redis.conf
查看主复制情况
[root@wyq63 ~]# redis-cli -h 10.10.10.63 -p 8000 info replication
# Replication
role:master
connected_slaves:2
slave0:ip=10.10.10.65,port=8000,state=online,offset=29,lag=0
slave1:ip=10.10.10.64,port=8000,state=online,offset=29,lag=0
master_repl_offset:29
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:28
查看从复制情况
[root@wyq63 ~]# redis-cli -h 10.10.10.64 -p 8000 info replication
# Replication
role:slave
master_host:10.10.10.63
master_port:8000
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:211
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
3. 配置redis-sentinel(主从服务器配置都一样)
[root@wyq63 ~]# vim /etc/redis-sentinel.conf
daemonize yes #开启后台守护进程
port 6800 #端口
bind 0.0.0.0 #绑定所有地址
logfile /var/log/redis/sentinel.log
pidfile /var/run/sentinel.pid
#master8000为实例名称,监听主服务器(10.10.10.63)8000端口,
#这里的2表示,如果2台sentinel认为主redis挂了,才算挂
sentinel monitor master8000 10.10.10.63 8000 2
#如果5秒内master8000没有响应,就认为SDOWN
sentinel down-after-milliseconds master8000 5000
sentinel failover-timeout master8000 15000
#自动切换后,执行脚本,实现vip自动漂移
sentinel client-reconfig-script master8000 /opt/notify_master6800.sh
添加/opt/notify_master6800.sh,实现vip自动漂移(主从服务器都要配置)
[root@wyq63 ~]# cat /opt/notify_master6800.sh
#!/bin/bash
MASTER_IP=$6 #第六个参数是新主redis的ip地址
LOCAL_IP='10.10.10.63' #这里记得要改,每台服务器写自己的本地ip即可
VIP='10.10.10.100'
NETMASK='24'
INTERFACE='ens32'#网卡接口设备名称
if [ ${MASTER_IP} = ${LOCAL_IP} ];then
/usr/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP绑定到该服务器上
/usr/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
/usr/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP从该服务器上删除
exit 0
fi
exit 1
启动redis-sentinel(主从服务器全部启动)
redis-sentinel /etc/redis-sentinel.conf #指定redis-sentinel配置文件
查看主(从)服务器sentinel状态
[root@wyq63 ~]# redis-cli -h 10.10.10.63 -p 6800 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=master8000,status=ok,address=10.10.10.63:8000,slaves=2,sentinels=3
4. 绑定VIP到redis主服务器(第一次需要手动绑定,后面故障切换就不需要)
从服务器的sentinel状态可以看出,当前主redis服务器ip是10.10.10.63
[root@wyq63 ~]# ip addr add 10.10.10.100/24 dev ens32 #绑定vip到网卡上
[root@wyq63 ~]# arping -q -c 3 -A 10.10.10.100 -I ens32 #arp抑制
[root@wyq63 ~]# ip a #查看当前网卡ip状态
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:ad:9c:a1 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.63/24 brd 10.10.10.255 scope global ens32
valid_lft forever preferred_lft forever
inet 10.10.10.100/24 scope global secondary ens32#vip绑定成功
valid_lft forever preferred_lft forever
inet6 fe80::709:25dd:d1e8:815c/64 scope link
valid_lft forever preferred_lft forever
5. 通过VIP(10.10.10.100)测试连接redis-server和redis-sentinel
[root@wyq64 ~]# redis-cli -h 10.10.10.100 -p 8000 info replication #连接redis-server
# Replication
role:master
connected_slaves:2
slave0:ip=10.10.10.65,port=8000,state=online,offset=174706,lag=1
slave1:ip=10.10.10.64,port=8000,state=online,offset=174706,lag=1
master_repl_offset:174706
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:174705
[root@wyq64 ~]# redis-cli -h 10.10.10.100 -p 6800 info sentinel #连接redis-sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=master8000,status=ok,address=10.10.10.63:8000,slaves=2,sentinels=3
6. 故障测试
[root@wyq63 ~]# redis-cli -h 10.10.10.63 -p 8000 shutdown #关闭主redis
[root@wyq63 ~]# redis-cli -h 10.10.10.100 -p 6800 info sentinel #通过vip查看sentinel状态
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
#发现主redis已经切换到10.10.10.65这台从服务器上了
master0:name=master8000,status=ok,address=10.10.10.65:8000,slaves=2,sentinels=3
[root@wyq65 ~]# ip a #65从服务器上查看网卡ip绑定状态
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:0b:6a:b4 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.65/24 brd 10.10.10.255 scope global ens32
valid_lft forever preferred_lft forever
inet 10.10.10.100/24 scope global secondary ens32#发现VIP已经漂移过来了
valid_lft forever preferred_lft forever
inet6 fe80::5735:b898:abf3:bdec/64 scope link
valid_lft forever preferred_lft forever
到此,使用redis主从 + 哨兵(sentinel)+ 漂移VIP的方案搭建了一个redis高可用系统,但这个系统保证的是单个redis实例的高可用,所以适合业务比较小的应用。如果业务比较大,并发量比较高,建议搭建redis集群,比如官方redis cluster,还有开源的codings集群。
后续只需将挂掉的redis恢复,就会自动添加到实例中