Redis集群本身已经做到了高可用和横向扩展,但是,实际情况一些小的业务没必要上集群,单个实例就可以满足业务需求,那么我们就要想办法如何保证单个实例的高可用。
keepalived是主备模式,意味着总有一台浪费着。
下面我介绍一下redis主从+sentinel(哨兵)漂移VIP的方案
一:实验环境
#redis
10.192.203.102:6400 主库
10.192.203.107:6400 从库
10.192.203.206 VIP
#sentinel
10.192.203.102:26400 sentinel 本地节点
10.192.203.107:26400 sentinel 本地节点
10.192.203.201:26400 sentinel 仲裁节点
二:实验步骤
1:安装redis
分别在10.192.203.102,10.192.203.107,10.192.203.201上安装。
#下载源码,解压缩后编译源码。
-
wget http://download.redis.io/releases/redis-2.8.3.tar.gz
-
tar xzf redis-2.8.3.tar.gz
-
cd redis-2.8.3
-
make
#编译完成后,将redis.conf和Src目录下的redis-server、redis-benchmark、redis-cli文件拷贝到一个目录下。
-
mkdir /usr/local/redis
-
mkdir -p /data/redis/redis_sentinels
-
mkdir /data/redis/6400
-
cp redis.conf /usr/local/redis
-
cd src
-
cp redis-server /usr/local/redis
-
cp redis-benchmark /usr/local/redis
-
cp redis-cli /usr/local/redis
-
cd /usr/local/redis
#撰写redis配置文件
(10.192.203.102,10.192.203.107)
vi /etc/redis_6400.conf
-
daemonize yes
-
pidfile "/var/run/redis_6400.pid"
-
port 6400
-
bind 0.0.0.0
-
timeout 0
-
tcp-keepalive 60
-
loglevel notice
-
logfile "/data/redis/redis_6400.log"
-
maxmemory 8gb
-
maxmemory-policy allkeys-lru
-
databases 16
-
save 900 1
-
save 300 10
-
save 60 10000
-
stop-writes-on-bgsave-error yes
-
rdbcompression yes
-
rdbchecksum yes
-
dbfilename "dump.rdb"
-
dir "/data/redis/6400"
-
slave-serve-stale-data yes
-
slave-read-only yes
-
repl-disable-tcp-nodelay no
-
slave-priority 100
-
appendonly no
-
appendfilename "appendonly.aof"
-
appendfsync everysec
-
no-appendfsync-on-rewrite no
-
auto-aof-rewrite-percentage 100
-
auto-aof-rewrite-min-size 64mb
-
lua-time-limit 5000
-
slowlog-log-slower-than 10000
-
slowlog-max-len 128
-
notify-keyspace-events ""
-
hash-max-ziplist-entries 512
-
hash-max-ziplist-value 64
-
list-max-ziplist-entries 512
-
list-max-ziplist-value 64
-
set-max-intset-entries 512
-
zset-max-ziplist-entries 128
2:撰写sentinel配置文件
(在10.192.203.102,10.192.203.107,10.192.203.201上)
vi /etc/redis-sentinel6400.conf
-
daemonize yes
-
port 26400
-
dir "/data/redis/redis_sentinels"
-
pidfile "/var/run/sentinel6400.pid"
-
logfile "/data/redis/redis_sentinels/sentinel6400.log"
-
sentinel monitor master6400 10.192.203.102 6400 2
-
sentinel down-after-milliseconds master6400 30000
-
sentinel failover-timeout master6400 180000
-
sentinel client-reconfig-script master6400 /opt/notify_master6400.sh
3:撰写漂移VIP的脚本
(10.192.203.102,10.192.203.107)
vi /opt/notify_master6400.sh
-
#!/bin/bash
-
MASTER_IP=$6
-
LOCAL_IP='10.192.203.102' #从库修改为10.192.203.107
-
VIP='10.192.203.206'
-
NETMASK='24'
-
INTERFACE='eth0'
-
if [ ${MASTER_IP} = ${LOCAL_IP} ]; then
-
/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE}
-
/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
-
exit 0
-
else
-
/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE}
-
exit 0
-
fi
-
exit 1
chmod +x /opt/notify_master6400.sh
这里大概说一下这个脚本的工作原理,sentinel在做failover的过程中会传出6个参数,分别是<master-name>、 <role>、 <state>、 <from-ip>、 <from-port>、 <to-ip> 、<to-port>,其中第6个参数from-ip也就是新的master的ip,对应脚本中的MASTER_IP,下面的if判断大家应该都很了然了,如果MASTER_IP=LOCAL_IP,那就绑定VIP,反之删除VIP。
4:启动redis服务
(10.192.203.102,10.192.203.107)
/usr/local/redis/redis-server /etc/redis_6400.conf
5:开放防火墙端口
如果防火墙是开启状态的话,需要开放相应的端口
在三台服务器上开放端口6400,26400
vi /etc/sysconfig/iptables
添加:
-A INPUT -m state --state NEW -m tcp -p tcp--dport 6400 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp--dport 26400 -j ACCEPT
#重启防火墙
service iptables restart
6:初始化主从
(10.192.203.107)
/usr/local/redis/redis-cli -p 6400 slaveof 10.192.203.102 6400
7:绑定VIP到主库
(10.192.203.102)
/sbin/ip addr add 10.192.203.206/24 dev eth0
可以使用ip addr命令进行验证,如:
-
[root@PC redis]# ip addr
-
1: lo: <LOOPBACK,UP,LOWER_UP> mtu16436 qdisc noqueue state UNKNOWN
-
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
-
inet 127.0.0.1/8 scope host lo
-
inet6 ::1/128 scope host
-
valid_lft forever preferred_lft forever
-
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP>mtu 1500 qdisc pfifo_fast state UP qlen 1000
-
link/ether 08:00:27:04:05:16 brd ff:ff:ff:ff:ff:ff
-
inet 10.192.203.102/24 brd 10.192.203.255 scope global eth0
-
inet 10.192.203.206/24 scope global secondary eth0
-
inet6 fe80::a00:27ff:fe04:516/64 scope link tentative dadfailed
-
valid_lft forever preferred_lft forever
8:启动sentinel服务
(10.192.203.102,10.192.203.107,10.192.203.201)
/usr/local/redis/redis-server /etc/redis-sentinel6400.conf --sentinel
至此,整个高可用方案已经搭建完成。
9:检查replication与Sentinel是否配置成功
#检查复制信息,确保有slave连接。
-
/usr/local/redis/redis-cli -h 10.192.203.102 -p 6400 info Replication
-
# Replication
-
role:master
-
connected_slaves:1
-
slave0:ip=10.192.203.107,port=6400,state=online,offset=127,lag=0
-
master_repl_offset:127
-
repl_backlog_active:1
-
repl_backlog_size:1048576
-
repl_backlog_first_byte_offset:2
-
repl_backlog_histlen:126
#检查Sentinel信息,确保status=ok
-
[root@PC redis]# /usr/local/redis/redis-cli-h 10.192.203.102 -p 26400 info Sentinel
-
# Sentinel
-
sentinel_masters:1
-
sentinel_tilt:0
-
sentinel_running_scripts:0
-
sentinel_scripts_queue_length:0
-
master0:name=master6400,status=ok,address=10.192.203.102:6400,slaves=1,sentinels=3
10:验证是否实现了高可用
1:停止主库
/usr/local/redis/redis-cli -h 10.192.203.102 -p 6400 shutdown
2:看从库是否提升为主库
[root@PC ~]# /usr/local/redis/redis-cli-h 10.192.203.107 -p 6400 info Replication
-
# Replication
-
role:master
-
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:验证VIP是否漂移
-
[root@PC ~]# ip addr
-
1: lo: <LOOPBACK,UP,LOWER_UP> mtu16436 qdisc noqueue state UNKNOWN
-
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
-
inet 127.0.0.1/8 scope host lo
-
inet6 ::1/128 scope host
-
valid_lft forever preferred_lft forever
-
2: eth0:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000
-
link/ether 08:00:27:04:05:16 brd ff:ff:ff:ff:ff:ff
-
inet 10.192.203.107/24 brd 10.192.203.255 scope global eth0
-
inet 10.192.203.206/24 scope global secondary eth0
-
inet6 fe80::a00:27ff:fe04:516/64 scope link tentative dadfailed
-
valid_lft forever preferred_lft forever
4:查看Sentinel监控状态
-
[root@PC redis]# /usr/local/redis/redis-cli-h 10.192.203.102 -p 26400 info Sentinel
-
# Sentinel
-
sentinel_masters:1
-
sentinel_tilt:0
-
sentinel_running_scripts:0
-
sentinel_scripts_queue_length:0
-
master0:name=master6400,status=ok,address=10.192.203.107:6400,slaves=1,sentinels=3
说明漂移成功。
11:配置PATH
修改.bash_profile文件,在PATH末尾添加:
:/usr/local/redis
source .bash_profile文件生效
--本文主要参考自“屌丝运维男”博客,并做了些许改动。