redis主从+哨兵sentinel+VIP高可用结构

守給你的承諾、 提交于 2020-08-20 08:56:11

前言

哨兵sentinel是redis自带的高可用程序,可以发现并自动切换主从状态的redis服务配置,而且哨兵sentinel还可以支持管理多套redis主从.

而应用可以通过类似jedis的驱动直接连接哨兵,来实现高可用.jedis会在哨兵sentinel里发现真实的主库地址,然后让程序连上真实主库地址操作.

不过这个架构有三个问题,第一,应用程序的配置要实现这个功能的话就要从连接真实IP的redis改成连接哨兵.第二,如果哨兵挂了,应用会报错而无法切换(3.2还会出现).第三,如果一套哨兵管理多套redis主从,并不是很好管理.

解决的方法有两个,一个是在哨兵前面加类似nginx的负载均衡来控制jedis访问哨兵地址,另一个就是在redis主从上加入高可用vip的操作来代替jedis直连哨兵,因为哨兵sentinel支持切换发生时接入脚本操作.

这篇文章说的就是加入高可用vip方式.


哨兵sentinel通信原理

在讲主题之前,我想想讲一下哨兵sentinel的原理.

通讯原理:

当一个完全没接入哨兵sentinel的redis主从里,第一个哨兵sentinel主动和redis主库通信,询问有没有其他的redis从库和哨兵sentinel连接信息.如果没有,这个哨兵sentinel就创建配置,等待同步其他哨兵信息.

然后,第二个哨兵连进redis主库,询问有没有其他从库和哨兵地址,这个时候,redis主库告诉它有其他哨兵,这个时候,第二个哨兵就会主动和第一个哨兵同步哨兵信息,从而形成了两个节点的哨兵sentinel集群.

再然后,第三个,第四个哨兵也是如此同步信息,形成以个更大的集群.

切换原理:

当一个哨兵发现主库down了,会发送一个主观挂起信息sdown给其他各个节点的哨兵,当其他哨兵的大多数(可以设定个数)都觉得主库确实挂起down了,这时哨兵集群内部会获得了一个客观挂起信息odown状态,那么第一个发起主观挂起信息的哨兵sentinel才会开始正式的redis主从切换工作.如果获取不到足够多的哨兵返回客观挂起down信息,是不会触发切换的,很好的避免了一些网络原因导致的闪断切换.

切换过程会把从库提为主库,而主库会变成从库,如果故障主库没起来,虽然会切换不成功,但是从库会继续切换成主库,而当故障主库从新起来后,哨兵sentinel会主动连上去把他的状态改成从库,然后新从库会自动重新同步主从数据和结构,不需要人为干预.

最后,哨兵sentinel间会通信,从新同步最新的redis主从信息,等待下一次的切换,这个间隔时间也可以设置,一般是3秒.


搭建环境

怎么搭建redis主从不是本文重点,所以就不展开说明了,只列举相关重要参数.

打开redis配置文件redis.conf

#本机redis密码
requirepass "123123"
#当本机是从库时,主机的密码,通常为了避免麻烦,会和上面一致,但是确实可以和上面不一致
masterauth "123123"
#当本机是从库时,主机的地址和端口
slaveof 172.25.111.187 6379

然后,后面来说哨兵sentinel的配置,打开配置文件sentinel.conf

#绑定可访问的地址,0.0.0.0就是所有
bind 0.0.0.0
#网络保护模式,no是外部网络可以直接访问,yes是需配置bind ip或者设置访问密码,哨兵不涉及数据,通常不需要配置密码
protected-mode no
#访问端口
port 26379
#数据目录,pid和日志log
dir "/data/redis/data"
pidfile "/data/redis/data/config/sentinel_26379.pid"
logfile "/data/redis/data/logs/sentinel_26379.log"
#允许后台运行
daemonize yes
#需要监听的redis主库信息,
#jdzxyd_189:项目名,随便你改,只要你能懂就行
#172.25.111.187:主库的IP地址,记住是主库的
#6379:主库的redis端口
#3:主观挂起信息sdown确认个数,也就是说,如果3台sentinel认为主redis挂了,才算真的挂,返回odown状态.
sentinel monitor jdzxyd_189 172.25.111.187 6379 3
#确认挂起的时间,也就是说如果5秒内jdzxyd_189项目的主库没有响应,就认为SDOWN,单位是毫秒
sentinel down-after-milliseconds jdzxyd_189 5000
#failover过期时间.当failover开始后,在此时间内jdzxyd_189项目仍然没有触发任何failover操作,当前sentinel将会认为此次failoer失败.单位是毫秒
sentinel failover-timeout jdzxyd_189 15000
#这个jdzxyd_189项目的认证密码
sentinel auth-pass jdzxyd_189 123123
#failover之后重配置客户端,jdzxyd_189项目执行脚本时会传递大量参数,请参考相关文档,这个脚本是用来配置VIP的
sentinel client-reconfig-script jdzxyd_189 /root/yw/change_vip_6379.sh

可能有人有疑问,究竟多少个哨兵才算是合理的.鉴于我们monitor的参数可以设置,我们可以参考zookeeper的概念,就是大多数原则,如果总数是3台哨兵,那么monitor就设置2台,如果总数是5,那么monitor就设置3台,如此类推.不过也要注意到的是,过多的哨兵,会影响切换时效速度,所以还是要综合衡量.还有就是,别忘了一个哨兵是可以管理多个redis主从的,你可以考虑公共哨兵集群+私有哨兵集群组合方式,灵活多变.

然后,我们看看切换vip的脚本

#!/usr/bin/env bash
#从哨兵client-reconfig-script传过来的参数中,$6就是新主库的IP,所以我们要获取它
MASTER_IP=$6
#高可用HA的vip地址
VIP='172.25.111.189'
#子网
NETMASK='24'
#网卡名称
INTERFACE='ens160'
#虚拟网卡编号
key='1'
ifctrl=/usr/sbin/ifconfig
arpingd=/usr/sbin/arping
sshh=/usr/bin/ssh
timeoutd=/usr/bin/timeout
#LOCAL_IP="`${ifctrl} ${INTERFACE}|grep 172.25|awk '{print $2}'|awk -F':' '{print $2}'`"
LOCAL_IP="`${ifctrl} ${INTERFACE}|grep 172.25|awk '{print $2}'`"
if [ ${MASTER_IP} = ${LOCAL_IP} ];then
    ping -c 1 ${VIP} > /dev/null 2>&1
    if [ $? -eq 0 ];then
        ${timeoutd} 5 ${sshh} -o stricthostkeychecking=no ${VIP} "${ifctrl} ${INTERFACE}:${key} down" >/dev/null 2>&1
    fi
    ${ifctrl} ${INTERFACE}:${key} ${VIP}/${NETMASK}
    ${arpingd} -q -c 1 -A ${VIP} -I ${INTERFACE}
    exit
else
    ${ifctrl} ${INTERFACE}:${key} down
    exit
fi

脚本功能就不打算细说了,自己研究下,不过我想强调的是,编写脚本的时候,一定要注意环境,因为linux不认windows的字符编码,容易出现奇葩的事情.

一切就绪,就在主库挂上vip,启动redis和哨兵,那这个集群就完事了

ifconfig ens160:1 172.25.111.189/24
/usr/local/bin/redis-server /data/redis/data/config/redis_6379.conf >/var/log/redis_6379.log 2>&1
/usr/local/bin/redis-sentinel /data/redis/data/config/sentinel_26379.conf >/var/log/sentinel_26379.log 2>&1


切换解析

我们可以从哨兵日志/data/redis/data/logs/sentinel_26379.log看到切换的过程,可以看到有sdown,odown和脚本启用的日志都在里面.


















易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!