
1.需求描述
在redis主从模式下,当master服务意外停止或服务所在主机宕机或故障时,另一个redis服务会自动被slave变成master,提供读写服务。
2.需求分析
一开始主从模式如下:
当redis master挂掉后,原来的redis slave提升为master,客户端自动将请求切换到新的master,如下图:
原master恢复后,手动添加节点,作为slave加入原主从模式,如下图:
根据上述故障恢复流程,可以抽象出以下关键技术点:
master挂断后如何将slave提升为新的master?我如何通知客户端向新主人提出请求? 3.场景研究3.1 如何将slave提升为新的master
使用redis官方的sentinel组件。如下图:
使用一组哨兵节点监控redis主从节点。当主节点发生故障时,sentinel 会选择其中一个从节点作为主节点,并通知其他从节点与新的主节点同步数据,如下图:
问题:
使用一组哨兵集群监控所有reids主从节点。当需要监控的主从节点较多时,sentinel会不会出现性能瓶颈? Sentinel 不支持跨机房部署。空余房间是否需要哨兵监控? 3.2 如何通知客户端向新的master发送请求3.2.1 方案1
客户端每次请求时,首先从sentinel获取master地址,然后访问master节点。
客户端首先连接到sentinel节点,执行SENTINEL get-master-addr-by-name命令,返回给定名称的master的IP地址和端口号。如果此 master 正在执行故障转移操作,或者此 master 的故障转移操作已完成,则此命令返回新 master 的 IP 地址和端口号。通过获取的master地址和端口号访问master节点。
优点:
解决方案简单,不需要依赖其他组件或配置。
缺点:
业务端需要修改。在每次访问主节点之前,必须查询哨兵并再进行一次网络传输。 3.2.2 选项 2
VIP漂移,主节点所在机器配置VIP(虚拟IP地址),当主从切换时,VIP绑定到新主节点所在机器。
VIP漂移有两种触发方式:
1.哨兵主动触发
失败后sentinel触发VIP漂移,将VIP绑定到新的master
sentinel如何触发VIP漂移?
这里可以使用redis sentinel的一个参数client-reconfig-script
sentinel client-reconfig-script
当一个master由于failover而发生改变时,这个脚本将会被调用并且传递6个参数
、 、 、 、 、 、,
其中是新主redis的IP地址,可以在这个脚本里做VIP漂移操作。
例子:
sentinel client-reconfig-script master8000 /opt/notify_master6800.sh
修改三台服务器的redis-sentinel配置文件/etc/sentinel.conf,添加上面一行。然后在 /opt/ 目录下创建 notify_master6800.sh 脚本文件。此脚本执行 VIP 漂移操作。内容如下:
#notify_master6800.sh脚本内容
#!/bin/bash
MASTER_IP=$6 #第六个参数是新主redis的ip地址
LOCAL_IP='192.168.56.101' #其他两个服务器上为192.168.56.102,192.168.56.103
VIP='192.168.56.250'
NETMASK='24'
INTERFACE='eth1'
if [ ${MASTER_IP} = ${LOCAL_IP} ];then
/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP绑定到该服务器上
/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP从该服务器上删除
exit 0
fi
exit 1 #如果返回1,sentinel会一直执行这个脚本
优点:
对客户端透明,客户端不需要更改。故障转移响应很快。哨兵完成主从切换后,可以主动触发VIP漂移。
缺点:
只适用于单个redis的高可用。如果机器上部署了多个redis master,只有一个redis master出现故障,会导致VIP漂移,机器上其他master实例无法访问(因为其他master还在原机上,但是请求已经到达贵宾位置。在机器上)。您需要 ssh 权限才能执行 VIP 漂移相关命令。
2.由keepalived触发
在每个redis实例上的机器上启动一个keepalived服务,多个keepalived组中有一个keepalived master和多个backupredis从入门到高可用完整版,master上有一个VIP对外提供服务。
keepalived master 会向备份发送多播。当发生故障时,keepalived 检测到 redis master 不可用,并调用自定义停止脚本来杀死机器的 keepalived 进程。当keepalived备份收不到keepalived master的vrrp报文时,就认为keepalived master宕机了。这时候就需要根据vrrp的优先级选举一个backup作为master,这样才能保证路由器的高可用。
优点:
对客户端透明,客户端不需要更改。无需通过脚本修改VIP,keepalived会自动设置。
缺点:
keepalived服务应该部署在redis所在的每台机器上。 VIP漂移有一定的延迟,取决于keepalived健康检查周期。不适合单机部署多个redis实例。
VIP漂移方案总结:
只适合单redis高可用,不适合本机部署多个redis实例。
3.2.3 选项三
使用consul服务发现组件,架构图如下:
在redis节点所在的机器上部署了一个consul客户端,主要负责与consul服务器进行通信。 redis 节点通过 consul 客户端向 consul 服务器注册自己作为服务。同一组主从节点注册的服务名称相同。查询 consul server 时,相同的服务名称将返回该名称下所有可用的服务 IP 地址和端口。 redis节点注册服务时会提供自定义的健康检查脚本,consul客户端会定期执行健康检查脚本。脚本返回 0 表示服务可用,返回 2 表示服务不可用。健康检测脚本主要判断节点的角色是否为master。如果是master,则返回0,表示服务可用;如果返回 2,则表示服务不可用。在consul集群中查询test_redis服务时,由于slave的健康检查不可用,所以只返回master的地址。
发生故障转移时:
sentinel 将slave 1 提升为master 后,节点的健康检查脚本发现服务的角色已变为master,因此健康检查通过,服务可用。在consul集群中查询test_redis服务,返回新master的IP地址和端口号。
上述failover过程中,客户端先查询consul服务器获取可用的master地址,然后通过master地址访问redis服务,类似方案一中的第一个query sentinel,然后连接master 如果采用这种方案,consul组件的引入是多余的,也没有方案1那么简单。那么有没有更优雅的方式通过consul获取master地址呢? – 领事 DNS 接口。
通过consul DNS接口自动发现服务:
服务注册到consul后,consul会为服务生成一个域名,如test_redis.service.consul,后缀为service.consul 客户端通过域名访问服务,配置DNS服务器在局域网中,consul后缀的域名被转发到conusl服务器机器上。 consul服务器的DNS端口是8600,默认的DNS端口是53,可以由dnsmasq服务。在consul服务器机器上,启动dnsmasq服务redis从入门到高可用完整版,将consul域名转发到8600端口,这样就可以通过consul服务器返回域名对应的服务地址了。
优点:
客户端通过域名访问服务,无需其他调整,后端切换master地址对客户端透明。与VIP漂移相比,更加灵活,支持一台机器上多个redis主从实例的高可用。
缺点:
引入了新的consul和dnsmasq组件,所有redis机器都需要安装consul客户端服务。
请登录后发表评论
注册
社交帐号登录