redis主从故障PHP自动切换IP

redis高可用方案,redis+sentinel redis自带监控中间件,当一个主redis不能提供服务时,redis sentinel可以将一个从redis升级为主redis,并对其他从redis进行配置,确保redis服务高可用。

这里随之带来一个问题,当redis发生主从切换时,ip地址是会变化的,应用程序(如PHP程序)如何获取当前的主redis的IP地址和端口信息呢?

这里说下php的常见解决方案,有以下2种:

一,通过sentinel提供的接口实现

redis-sentinel提供了接口,请求任何一个sentinel,发送sentinel get-master-addr-by-name <master name>就能获取到当前主reids的ip和port,php请求sentinel程序代码:

$sentinel = new \RedisSentinel\Sentinel(); $sentinel->connect(127.0.0.1, 6379); $address = $sentinel->getMasterAddrByName(mymaster); $redis = new Redis(); $redis->connect($address[ip], $address[port]); $info = $redis->info(); print_r($info);

这种方法的缺点就是每次操作redis至少需要发送两次连接请求,第一次请求sentinel,第二次才真正请求redis,那么看下第二种方案。

二,VIP漂移

漂移VIP可以用keepalived实现,这里就不多做介绍了。

VIP的方案是,redis集群对外始终是同一ip地址,当reids发生故障转移时将VIP从之前的redis服务器漂移到新的主redis服务器上,这里用到了redis sentinel的一个参数client-reconfig-script,这个参数可配置执行脚本,当sentinel在做主从切换时会执行这个脚本,并传以下参数<master-name>、<role>、<sate>,<from_ip>,<from_port>,<to_ip>,<to_port>,其中<to_ip>就是新主redis的IP地址,可以在这个脚本中把VIP漂移到新主redis上。

在redis-sentinel配置文件增加配置切换脚本

sentinel client-reconfig-script mymaster /opt/notify_master.sh

漂移脚本

#!/bin/bash MASTER_IP=$6#第六个参数是新主redis的ip地址 LOCAL_IP=192.168.1.101 VIP=192.168.1.250 NETMASK=24 INTERFACE=eth1 if [ ${MASTER_IP} = ${LOCAL_IP} ];then /sbin/ipaddradd ${VIP}/${NETMASK}dev ${INTERFACE}#将VIP绑定到该服务器上 /sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE} exit 0 else /sbin/ipaddr del${VIP}/${NETMASK}dev ${INTERFACE} #将VIP从该服务器上删除 exit 0 fi exit 1#如果返回1,sentinel会一直执行这个脚本

应用程序链接VIP地址即可,通过VIP地址连接redis,这个方案比起上面那种少了一次哨兵的连接,更高效些。

三、总结

redis主从+哨兵+漂移VIP搭建的redis高可用,这个系统保证的是单个redis实例的高可用,如果redis并发量比较高,建议使用官方的redis cluster。