Redis高可用部署方案
Redis Sentinel 集群 + Keepalived+自定义脚本,sentinel故障切换策略需要按投票数选举新主机,投票数(redis部署数量)必须为单数,所以此方案至少要求3台设备,每台设备都运行redis和sentinel服务。
1. Redis安装
redis的安装参考部署手册.doc,安装后按照此文档进行高可用方案部署,方案中涉及到的名称和IP汇总如下:
名称 | IP | Port | 说明 |
---|---|---|---|
虚拟IP | 10.10.10.140 | 6380 | keepalived配置 |
redis141 | 10.10.10.141 | 6380 | redis主服务 |
redis142 | 10.10.10.142 | 6380 | redis从服务 |
redis143 | 10.10.10.143 | 6380 | redis从服务 |
sentinel141 | 10.10.10.141 | 26380 | sentinel服务 |
sentinel142 | 10.10.10.142 | 26380 | sentinel服务 |
sentinel143 | 10.10.10.143 | 26380 | sentinel服务 |
2. Redis主从配置
redis配置文件位置一般为 /etc/redis-6380.conf,配置文件名称一般加上端口号便于识别,redis服务启动需要指定配置文件。
主服务关键配置
vi /etc/redis-6380.conf
# ---------------------
# redis后台运行模式
daemonize yes
# 绑定本地ip
bind 0.0.0.0
# 端口,默认为6379,强烈建议修改为其他端口
port 6380
# 密码,默认无密码,强烈建议添加密码
requirepass zh@123
# 主从切换后保证主服务也能无缝变为从服务,需要如下参数连接主服务
# sentinel会自动加上slaveof 10.10.10.141 6380
# redis主服务密码
masterauth zh@123
# ---------------------
从服务关键配置
vi /etc/redis-6380.conf
# ---------------------
# redis后台运行模式
daemonize yes
# 绑定本地ip
bind 0.0.0.0
# 端口,必须与redis主服务保持一致
port 6380
# 密码,必须与redis主服务保持一致
requirepass zh@123
# redis主服务ip和端口
slaveof 10.10.10.141 6380
# redis主服务密码
masterauth zh@123
# ---------------------
校验主从服务
确认主从关系
# 1. 三台redis服务均启动
# 启动redis服务(指定配置文件)
redis-server /etc/redis-6380.conf
# 2. 在redis141查询主从状态,替换参数-p端口和-a密码
redis-cli -p 6380 -a zh@123 info Replication
#查询返回如下信息表示该redis服务角色为master,从服务有2个以及从服务的ip端口和状态
# ---------------------------
role:master
connected_slaves:2
slave0:ip=10.10.10.142,port=6380,state=online,offset=34903,lag=1
slave1:ip=10.10.10.143,port=6380,state=online,offset=34903,lag=1
# ---------------------------
# 3. 分别在redis142和redis143上登陆redis从服务,查询数据
redis-cli -p 6380
#查询返回如下信息表示该redis服务角色为slave,主服务的ip和端口以及连接状态必须为up
# ---------------------------
role:slave
master_host:10.10.10.141
master_port:6380
master_link_status:up
# ---------------------------
校验主从复制功能
主redis上添加数据,在从redis上能查询刚刚添加的数据则表示主从复制功能正常。
# 1. 三台redis服务均启动
# 2. 在redis141登陆redis主服务
redis-cli -p 6380 -a zh@123
# 进入redis-cli运行环境执行如下命令
# -------------------------------
# 添加数据,返回OK表示数据添加成功
set name abc
# 查询数据,返回abc表示数据正确
get name
# -------------------------------
# 3. 分别在redis142和redis143上登陆redis从服务,查询数据
redis-cli -p 6380 -a zh@123
# 进入redis-cli运行环境执行如下命令
# -------------------------------
# 查询数据,返回abc表示主从复制功能正常
get name
# -------------------------------
3. Sentinel配置
sentinel中文名为哨兵,用于监控集群部署时各redis服务状态,在redis主服务出现故障时选举一个redis从服务变为主服务,实现故障转移高可用。
首次设置虚拟IP
首次启动需手动设置虚拟IP,后续故障转移会触发sentinel执行虚拟IP漂移脚本,来切换虚拟IP。
# 手动在redis主机上执行如下命令,添加虚拟ip
ip addr add 10.10.10.140/32 dev eth0
arping -q -c 3 -A 10.10.10.140 -I eth0
# 检查每个redis,若果redis不是主,但是有虚拟ip飘在上面,需要手动删除虚拟ip
ip addr del 10.10.10.140/32 dev eth0
虚拟IP漂移脚本
sentinel监控到redis服务故障并进行故障转移后会触发此脚本,完成虚拟ip的映射。
# 在redis141,redis142,redis143上新建并编辑脚本
# 脚本的返回值如果为0表示执行成功,sentinel停止调用,如果为1表示执行失败,sentinel继续循环调用此脚本
vi /usr/local/redis/switch_vip_to_master.sh
# -----------------------------------------
#!/bin/sh
# sentinel调用脚本的第6个参数是新主redis的IP地址
MASTER_IP=$6
# 本地IP地址
LOCAL_IP='10.10.10.141'
# 虚拟IP
VIP='10.10.10.140'
# 子网掩码
NETMASK='32'
# 网卡名称
INTERFACE='eth0'
# 如果如果新的redis服务IP与本机服务IP相同,则将虚拟IP绑定本机,如果不相同则删除本机的虚拟IP
if [ ${MASTER_IP} = ${LOCAL_IP} ];then
# 将VIP绑定到该服务器上
ip addr add ${VIP}/${NETMASK} dev ${INTERFACE}
#向相邻主机发送ARP请求, -q 不显示警告信息, -c发送的数据包的数目(3), -A ARP回复模式,更新邻居,-I<网卡> 使用指定的以太网设备,默认情况下使用eth0
arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
# 将VIP从该服务器上删除
ip addr del ${VIP}/${NETMASK} dev ${INTERFACE}
exit 0
fi
exit 1
# -------------------------------------------
# 脚本创建完需要添加执行权限
cd /usr/local/redis/
chmod +x switch_vip_to_master.sh
sentinel配置
每个redis服务节点均部署sentinel服务,
# 在sentinel141,sentinel142,sentinel143机器上都需要执行如下操作
# 新建并编辑配置文件,复制粘贴如下内容
vi /etc/redis-sentinel-26380.conf
# --------------------------
# Sentinel的端口
port 26380
# 绑定本地ip
bind 0.0.0.0
# 后台运行模式
daemonize yes
dir "/usr/local/redis"
# 日志输出文件位置,文件名称加上端口号便于识别
logfile "/usr/local/redis/logs/sentinel-26380.log"
#以下配置项顺序很重要,请勿随意变更顺序
# 监控主节点的ip和port,以及定义主节点的名称
# 最后一个参数表示需要多少个sentinel服务检测到主节点服务异常,才能判断[主redis服务客观下线]
sentinel monitor mymaster 10.10.10.141 6380 2
# 主节点的密码
sentinel auth-pass mymaster zh@123
# 配置sentinel向master发出ping,最大响应时间.超过则认为主观下线
sentinel down-after-milliseconds mymaster 5000
# 故障转移后同时向新主节点发起复制的节点数量,避免在故障切换时候的网络和磁盘IO性能问题
sentinel parallel-syncs mymaster 1
# 配置当出现failover时下一个sentinel与上一个sentinel对[同一个master监测的
sentinel failover-timeout mymaster 18000
# 故障转移结束后会触发执行脚本,先注释,测试虚拟ip漂移时再启用
#sentinel client-reconfig-script mymaster /usr/local/redis/switch_vip_to_master.sh
# --------------------------
防火墙配置
sentinel需要通过tcp协议进行通讯
# 在sentinel141,sentinel142,sentinel143上执行
vi /etc/sysconfig/iptables
#在redis6380端口条目下添加sentinel服务端口防火墙条目
# ------------------------
#-A INPUT -p tcp -m state --state NEW -m tcp --dport 6380 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 26380 -j ACCEPT
# ------------------------
#重启iptables服务
service iptables restart
校验sentinel服务
# 在sentinel141,sentinel142,sentinel143机器上都需要执行如下操作
# 确认部署redis服务时已执行过如下软连接创建
#ln -s /usr/local/bin/redis-sentinel /usr/bin/redis-sentinel
# 启动sentinel服务(指定配置文件)
redis-sentinel /etc/redis-sentinel-26380.conf
# 3个sentinel服务均启动后分别登陆查询sentinel服务状态
redis-cli -p 26380 info Sentinel
# 表示sentinel服务正常,slaves=2,sentinels=3
# -----------------------------
# 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=10.10.10.141:6380,slaves=2,sentinels=3
# -----------------------------
测试主从切换
三台设备的redis服务和sentinel服务均运行中,关闭redis主服务,查看redis主从状态变化和sentinel日志输出。
# 在redis141上执行
# 关闭redis141服务,替换参数-p端口和-a密码
redis-cli -p 6380 -a zh@123 shutdown
# 在redis142上执行
# 查询redis主从状态
redis-cli -p 6380 -a zh@123 info Replication
# 如下内容表示redis142位slave角色,master指向了redis143
# -------------------------------------------
role:slave
master_host:10.10.10.143
master_port:6380
master_link_status:up
# -------------------------------------------
# 在redis143上执行
# 查询redis主从状态
redis-cli -p 6380 -a zh@123 info Replication
# 如下内容表示redis143变更为master角色,有1个slave连接他
# -------------------------------------------
role:master
connected_slaves:1
slave0:ip=10.10.10.142,port=6380,state=online,offset=61316,lag=0
# -------------------------------------------
# 查询sentinel142和sentinel143的sentinel服务日志输出
tail -f /usr/local/redis/logs/sentinel-26380.log
# 如果包含如下内容则表示redis主从关系已成功变更
# ------------------------------------------
+switch-master mymaster 10.10.10.141 6380 10.10.10.143 6380
# ------------------------------------------
sentinel自启动
#设置开机启动
#让Redis-sentinel开机运行可以将其添加到rc.local文件
echo "/usr/bin/redis-sentinel /etc/redis-sentinel-26380.conf" >> /etc/rc.local
4. 测试故障转移
依照步骤3中测试主从切换的章节描述执行命令,在测试机用命令行客户端连接虚拟IP和端口登陆redis,执行redis命令。
redis-cli -h 10.10.10.140 -p 6380 -a zh@123
#登陆成功后在redis-cli环境中执行查询命令
# -----------------------------------------
get name
# -----------------------------------------
#故障转移后重复执行如上命令测试是否返回正常