基于腾讯云CVM自建高可用Redis实践

本文来源 | 云+社区专栏文章
做者 | 万守兵,腾讯云资深架构师。8年以上大型互联网公司运维工做经验,腾讯云资深迁云架构师,一直从事大型互联网服务端架构设计和优化工做。我的专一于云计算、k8s和 DevOps领域。php

导读:在企业实际生产环境中为了可以给业务上层应用提供高可靠、低延迟、低数据损失的Redis缓存服务,本文经过对目前主流的几种redis高可用方案进行对比分析,并基于腾讯云CVM和HAVIP等基础产品进行搭建、配置、测试、总结,供你们参考。前端

01环境说明redis

1.需求与目标docker

本文将经过对目前主流的几种redis高可用方案进行对比分析,并基于腾讯云CVM和HAVIP等基础产品进行搭建、配置、测试、总结。vim

2.软件版本缓存

redis用3.2.8版本,keepalived用1.2.19版本。bash

3.基本环境服务器

采用同一网络内的三台主机(能够是物理主机、虚拟机或docker容器),要求三台主机之间都能相互访问。我这里使用腾讯云上3台CVM,每台CVM上开启一个redis-server、redis-sentinel和keepalived服务,redis-server端口为6379,redis-sentinel的端口为26379(我这里用默认端口,生产环境中能够修改默认端口),3台CVM上都安装keepalived服务。微信

clipboard.png

02几种redis高可用方案说明网络

1.通常的主从复制方案

因为redis目前只支持主从复制备份(不支持主主复制),当主redis挂了,从redis只能提供读服务,没法提供写服务。因此,还得想办法,当主redis挂了,让从redis升级成为主redis。

优势:
(1)实现了对master数据的备份,一旦master出现故障,slave节点能够提高为新的master,顶替旧的master继续提供服务

(2)实现读扩展。使用主从复制架构, 通常都是为了实现读扩展。Master主要实现写功能, Slave实现读的功能

缺点:
(1)一旦主节点宕机,从节点晋升成主节点,同时须要修改应用方的主节点地址,还须要命令全部从节点去复制新的主节点,整个过程须要人工干预,此时须要通过以下操做(假设提高Slave1为Master):

在Slave1上执slaveof no one命令提高Slave1为新的Master节点
在Slave1上配置为可写,这是由于大多数状况下,都将slave配置只读
告诉Client端(也就是链接Redis的程序)新的Master节点的链接地址
配置Slave2重新的Master进行数据复制

(2)主节点的写能力受到单机的限制

(3)主节点的存储能力受到单机的限制

2.sentinel高可用方案

客户端程序(如PHP程序)链接redis时须要ip和port,但redis-server进行故障转移时,主redis是变化的,因此ip地址也是变化的。客户端程序如何感知当前主redis的ip地址和端口呢?redis-sentinel提供了接口,请求任何一个sentinel,发送SENTINEL get-master-addr-by-name <master name>就能获得当前主redis的ip和port。须要注意的是,Redis Sentinel 端口和 Redis 主节点均须要开放访问权限。若是前端业务使用 Java,有 JedisSentinelPool 能够复用;若是前端业务使用 PHP,能够在 phpredis 的基础上作二次封装。

优势:
(1)redis sentinel带有自动故障转移功能(failover),当一个主redis不能提供服务时,redis sentinel能够将一个从redis升级为主redis,并对其余从redis进行配置,让它们使用新的主redis进行复制备份;

(2)服务探测故障及时;

(3)DBA 维护成本低。

缺点:
(1)对应用有入侵性:客户端每次链接redis前,先向sentinel发送请求,得到主redis的ip和port,而后用返回的ip和port链接redis。每次操做redis至少须要发送两次链接请求,第一次请求sentinel,第二次请求redis;

(2)Sentinel服务器和Redis节点须要开放访问权限。

3.redis-sentinel+VIP方案+自定义脚本方案

底层是Redis Sentinel 集群,代理着 Redis 主从,Web端经过VIP提供服务。在部署Redis主从的时候,须要将虚拟IP绑定到当前的Redis 节点。当主节点发生故障,好比机器故障、Redis节点故障或者网络不可达,Sentinel 集群会调用 client-reconfig-script 配置的脚本,将VIP漂移到新的主节点上。

好比:当前redis系统中主redis的ip地址是172.16.2.4,那么VIP(172.16.2.250)指向172.16.2.4,客户端程序用VIP(172.16.2.250)地址链接redis,实际上链接的就是当前主redis,这样就避免了向sentinel发送请求。

优势:
(1)脚本自定义,架构可控;

(2)对应用透明,当主redis宕机,进行故障转移时,192.168.56.102这台服务器上的redis提高为主,这时VIP(172.16.2.4)指向192.168.56.102,这样客户端程序不须要修改任何代码,链接的是192.168.56.102这台主redis;

(3)秒级切换,在 5s 内完成整个切换操做.

缺点:
(1)使用VIP增长维护成本,存在IP混乱风险;

(2)须要自行编写VIP切换脚本,须要经过ip addr手动先在主redis上配置vip,配置相对复杂;

(3)Sentinel模式存在短期的服务不可用;

(4)应用场景局限于内网,例如部分业务只能经过外网访问Redis时,该方案不可用

注意:
VIP方案对配置的环境有必定的要求,在腾讯云上搭建redis,须要用到腾讯云HAVIP,文档见:https://cloud.tencent.com/doc...

clipboard.png

4.redis-sentinel+keepalived方案

keepalived经过vrrp_script检测当前主机上的redis-server是否以master状态运行,若是当前主机上的redis-server正在以master状态运行,则将vrrp_instance标记为存活状态,并分配VIP;若是当前主机上的redis-server正在以slave状态运行,则将vrrp_instance标记为错误状态。当某台主机宕机后,其余两台主机上的keepalived会将VIP切换到新的master(当前主机上的redis-server正在以master状态运行)上。

优势:
(1)相对redis-sentinel+VIP方案,不需编写VIP切换脚本,配置更简洁、清晰;

(2)对应用透明;

(3)秒级切换。

缺点:
(1)对网络环境有要求:keepalived的核心协议VRRP使用IP多播数据包进行封装,组地址为224.0.0.18,发布范围只限于同一局域网内,并且在网络不受本身控制时基本不能用,可是腾讯云是支持组播协议,可使用keepalived;

(2)存在脑裂;

(3)Sentinel模式存在短期的服务不可用

注意:
keepalived方案也须要一个VIP,且网络要能支持组播协议。

03安装部署
方案一:sentinel高可用方案

1.首先下载安装redis:(http://download.redis.io/rele...
$ wget http://download.redis.io/rele...

$ tar -zxvf redis-3.2.8.tar.gz

$ cd redis-3.2.8

$ make (若是没有安装gcc会报错,因此强烈建议在make以前先yum install gcc先安装gcc)
make报错以下:(make是用来编译的,从Makefile中读取指令,安装到指定的位置)

make3: gcc: Command not found
make3: * net.o Error 127
make3: Leaving directory `/opt/redis-3.2.8/deps/hiredis'
make2: * hiredis Error 2
make2: Leaving directory `/opt/redis-3.2.8/deps'
make1: persist-settings Error 2 (ignored)
CC adlist.o
/bin/sh: cc: command not found
make1: * adlist.o Error 127
make1: Leaving directory `/opt/redis-3.2.8/src'
make: * all Error 2
安装gcc:

yum install gcc
继续编译:

make
Make报错以下:

make1: Entering directory `/opt/redis-3.2.8/src'
CC adlist.o
In file included from adlist.c:34:0:
zmalloc.h:50:31: fatal error: jemalloc/jemalloc.h: No such file or directory

include <jemalloc/jemalloc.h>

^
compilation terminated.
make1: * adlist.o Error 1
make1: Leaving directory `/opt/redis-3.2.8/src'
make: * all Error 2
从新编译:

make MALLOC=libc
编译成功!!!

2.基本配置:

(1)make完后 redis-3.2.8目录下会出现编译后的redis服务程序redis-server,还有用于测试的客户端程序redis-cli,两个程序位于安装目录 src 目录下:

复制redis相关命令到/usr/sbin目录下,这样就能够直接执行这些命令,不用写全路径。

$ cd src

$ cp redis-cli redis-server redis-sentinel /usr/sbin/
(2)在redis目录下有redis.conf和sentinel.conf配置文件示例,将两个配置文件复制到/etc目录下(固然也能够在/etc/目录新建配置文件),而后修改配置文件

$ cp redis.conf sentinel.conf /etc/
(3)redis.conf 是一个默认的配置文件。咱们能够根据须要修改配置文件

●修改主redis-server(172.16.2.4)配置文件内容以下:

不修改,使用默认端口

port 6379

修改成0.0.0.0,能够从外部链接redis服务端

bind 0.0.0.0

默认状况下redis运行在保护模式(这种模式下,访问不须要密码),可是这种模式只容许本地回路访问,这里改成no

protected-mode no

默认状况下,redis不是在后台模式运行的,若是须要在后台进程运行,把该项的值更改成yes,默认为no

daemonize yes

redis服务之后台进程运行的时候,Redis默认会把pid写入/var/run/redis.pid文件组

pidfile /var/run/redis.pid

开启AOF持久化,默认是关闭的,RDB默认是开启的,可是AOF的优先级更高,启动时Redis 会优先载入 AOF 文件来恢复数据,与 RDB 相比,AOF 的实时性更好,所以已成为主流的持久化方案

若是不但愿丢掉任何一条数据的话就该用纯累加模式:一旦开启这个模式,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件。

appendonly yes

● 修改从redis-server(172.16.2.2和172.16.2.15)配置文件内容以下:

不修改,使用默认端口

port 6379

修改成0.0.0.0,能够从外部链接redis服务端

bind 0.0.0.0

默认状况下redis运行在保护模式(这种模式下,访问不须要密码),可是这种模式只容许本地回路访问,这里改成no

protected-mode no

默认状况下,redis不是在后台模式运行的,若是须要在后台进程运行,把该项的值更改成yes,默认为no

daemonize yes

redis服务之后台进程运行的时候,Redis默认会把pid写入/var/run/redis.pid文件组,改成yes

pidfile /var/run/redis.pid

开启AOF持久化,默认是关闭的,RDB默认是开启的,可是AOF的优先级更高,启动时Redis 会优先载入 AOF 文件来恢复数据,与 RDB 相比,AOF 的实时性更好,所以已成为主流的持久化方案

若是不但愿丢掉任何一条数据的话就该用纯累加模式:一旦开启这个模式,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件。

appendonly yes

从redis比主redis多这一行,使用slaveof实现主从复制

slaveof 172.16.2.4 6379
● 启动redis服务以前,建议先修改kernel参数,重启生效

vim /etc/sysctl.conf

表示内核容许分配全部的物理内存,而无论当前的内存状态如何

vm.overcommit_memory = 1

定义了TCP全链接队列长度,默认128过小,启动redis服务会报错

net.core.somaxconn = 511

使配置文件永久生效

sysctl -p
(4)启动redis-server服务:

$ redis-server & #加上‘&’号使redis之后台程序方式运行

$ redis-server /etc/redis.conf #经过指定配置文件启动,在生产环境中强烈建议使用这种方式启动服务
(5)中止:

使用客户端:

$ redis-cli shutdown
由于Redis能够妥善处理SIGTERM信号,因此直接kill -9也是能够的

$ kill -9 PID
(6)启动redis服务进程后,就可使用测试客户端程序redis-cli和redis服务交互了,链接redis-server:

$ redis-cli #本地链接redis-server,若是要链接远程redis,redis-cli -h host -p port -a password

redis> set key1 value1

OK

redis> get key1

"value1"
(7)查看主从状态:

经过redis-cli 进入主redis命令行,执行info replication查看当前主从配置,能够发现两个从节点信息,代表redis-server主从已经配置完毕。

redis> INFO replication
clipboard.png

查看redis主从关系已经创建

● 可能遇到的问题:redis主从创建失败,有多是启动服务时没有指定正确的配置文件

● 解决思路:

(1)经过ps -ef查看服务进程ID

(2)经过lsof -p pid查看进程打开的文件,若是打开文件有误,经过redis-server /etc/redis.conf指定正确的配置文件从新启动服务

(8)搭建redis-sentinel系统:

redis-sentinel程序上面已经安装过了,这里只须要修改配置文件就能够了。修改/etc/sentinel.conf以下:

● 三台sentinel服务器配置都一致

当前Sentinel服务运行的端口

port 26379

监控的master的名字叫作mymaster(自定义),地址为172.16.2.4:6379,行尾最后的一个2表明在sentinel集群中,多少个sentinel认为masters死了,才能真正认为该master不可用了

sentinel monitor mymaster 172.16.2.4 6379 2

每一个Sentinel节点都要按期PING命令来判断Redis数据节点和其他Sentinel节点是否可达,若是超过30秒且没有回复,则断定不可达

sentinel down-after-milliseconds mymaster 30000

当Sentinel节点集合对主节点故障断定达成一致时,Sentinel领导者节点会作故障转移操做,选出新的主节点,原来的从节点会向新的主节点发起复制操做,限制每次向新的主节点发起复制操做的从节点个数为1,在从Redis实例较多的状况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长

sentinel parallel-syncs mymaster 1

failover过时时间,当failover开始后,在此时间内仍然没有触发任何failover操做,当前sentinel将会认为这次failover失败。默认180秒,即3分钟。

sentinel failover-timeout mymaster 18000

若是Sentinel监控的主节点配置了密码,能够经过sentinel auth-pass配置经过添加主节点的密码,防止Sentinel节点没法对主节点进行监控。

例如:sentinel auth-pass mymaster MySUPER--secret-0123passw0rd

sentinel auth-pass

在故障转移期间,当一些警告级别的Sentinel事件发生(指重要事件,如主观下线,客观下线等)时,会触发对应路径的脚本,想脚本发送相应的事件参数。

例如:sentinel notification-script mymaster /var/redis/notify.sh

sentinel notification-script

在故障转移结束后,触发应对路径的脚本,并向脚本发送故障转移结果的参数。

例如:sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

sentinel client-reconfig-script
● 常见问题:在172.16.2.4(主redis)上查看sentinel的信息,发现报错

clipboard.png

查看sentinel服务报错

● 解决方案:修改/etc/sentinel.conf文件

缘由是sentinel没有指定bind和密码访问,因此被开启了protected-mode保护模式,拒绝其余sentinel的链接。致使进入了ODWON。在sentinel.conf里加入关闭保护,protected-mode no

protected-mode no

指定文件启动sentinel服务

redis-sentinel sentinel.conf &
3.测试验证:

(1)基本链接测试:

redis-cli -h host -p port info sentinel
三个redis-sentinel服务启动完毕后,链接任意sentinel服务能够获知当前主redis服务信息,说明sentinel服务已经成功起来

查看sentinel服务已经启动

clipboard.png

(2)测试sentinel的failover故障切换功能:

● 把主redis(172.16.2.4)停掉

redis-cli -h 172.16.2.4 -p 6379 shutdown
● 查看redis-sentinel的监控状态:

redis-cli -h 172.16.2.4 -p 26379 info sentinel

clipboard.png

查看sentinel信息发现master已经切换为172.16.2.2

● 发现172.16.2.2这台redis-server提高为主:

redis-cli -h 172.16.2.2 -p 6379 info replication

在master上查看主从状态

● 控制台也输出相关信息,表示主从切换成功。

clipboard.png

控制台log,redis主从切换成功

● 172.16.2.2切换成主以后,也能够执行写操做了。至此,redis的sentinel方案已经搭建完成。

clipboard.png

确认当前主能够执行写操做

4.客户端使用方式:

客户端程序(如PHP程序)链接redis时须要ip和port,但redis-server进行故障转移时,主redis是变化的,因此ip地址也是变化的。客户端程序如何感知当前主redis的ip地址和端口呢?redis-sentinel提供了接口,请求任何一个sentinel,发送SENTINEL get-master-addr-by-name<master name>就能获得当前主redis的ip和port。

● 链接到sentinel获取当前主redis的ip和端口(由于又执行了一次切换,这里的主已经切换到172.16.2.15,这里只是说明客户端的使用方式)

clipboard.png

客户端程序链接方式
方案二:redis-sentinel+vip方案

1.方案说明

VIP方案是redis系统对外始终是同一ip地址,当redis主从进行故障转移时,须要作的是将VIP从以前的redis服务器漂移到如今新的主redis服务器上。
好比:当前redis系统中主redis的ip地址是172.16.2.4,那么VIP(172.16.2.250)指向172.16.2.4,客户端程序用VIP(172.16.2.250)地址链接redis,实际上链接的就是当前主redis,这样就避免了向sentinel发送请求。

● 正常状况下VIP指向172.16.2.4

clipboard.png

正常状况下VIP指向172.16.2.4

● 故障状况下,VIP漂移指向172.16.2.2

clipboard.png

clipboard.png

master故障状况下,VIP自动漂移指向172.16.2.2

2.基本配置:

那么如今的问题是,如何在进行redis故障转移时,将VIP漂移到新的主redis服务器上。在方案一的配置基础之上增长对sentinel.conf的配置,具体配置以下:
(1)在sentinel.conf配置文件设置要执行的vip漂移的脚本

使用sentinel.conf配置文件的有一个参数client-reconfig-script,这个参数配置执行脚本,sentinel在作failover的时候会执行这个脚本,而且传递6个参数<master-name>、 <role>、 <state>、 <from-ip>、 <from-port>、 <to-ip> 、<to-port>,其中<to-ip>是新主redis的IP地址,能够在这个脚本里作VIP漂移操做。

修改三个服务器的redis-sentinel配置文件/etc/sentinel.conf,增长下面一行。

vi /etc/sentinel.conf

sentinel client-reconfig-script mymaster /opt/notify_mymaster.sh
(2)建立VIP漂移脚本(VIP用以前在腾讯云控制台上申请的VIP)

而后在/opt/目录下建立notify_mymaster.sh脚本文件,这个脚本作VIP漂移操做。
chmod 777 notify_mymaster.sh #赋予脚本执行权限
脚本内容以下:

notify_mymaster.sh脚本内容

!/bin/bash

MASTER_IP=$6 #第六个参数是新主redis的ip地址

LOCAL_IP='172.16.2.2' #其余两个服务器上为172.16.2.4,172.16.2.15

VIP='172.16.2.250'

NETMASK='24'

INTERFACE='eth0'

if [ ${MASTER_IP} = ${LOCAL_IP} ];then

sudo /sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP绑定到该服务器上

sudo /sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}

exit 0

else

sudo /sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE} #将VIP从该服务器上删除

exit 0

fi

exit 1 #若是返回1,sentinel会一直执行这个脚本
(3)第一次需在主redis上手工设置VIP

只须要第一次手工在主redis上设置vip,如今当前主redis是172.16.2.2,须要手动绑定VIP到该服务器上。(注意强烈建议加sudo执行)
sudo /sbin/ip addr add 172.16.2.250/24 dev eth0
sudo /sbin/arping -q -c 3 -A 172.16.2.250 -I eth0
3.测试验证

(1)配置完成以后,去另外一个服务器上(172.16.2.15)经过VIP地址链接redis-server和redis-sentinel。从上面能够看到主redis是172.16.2.2

clipboard.png

VIP成功绑定在master 172.16.2.2上

(2)验证:下面关闭这台主redis服务(172.16.2.2),看看VIP是否漂移到另外一台服务器上

redis-cli -h 172.16.2.2 -p 6379 shutdown
经过查询sentinel发现172.16.2.15提高为主。

clipboard.png

sentinel自动failover,将172.16.2.15提高为master

(3)经过访问VIP链接查看redis sentinel信息和redis-server主从关系,发现VIP确实指向了172.16.2.15

clipboard.png

经过VIP成功查看sentinel状态

clipboard.png

经过VIP成功查看redis的状态
方案三:redis-sentinel+keepalived方案

1.方案说明

VIP方案是经过sentinel服务在作redis主从切换的时候,经过配置文件sentinel.conf中的一个参数client-reconfig-script来执行相应的脚本,这种方式须要本身编写脚本。而keepalived方案经过vrrp_script检测当前主机上的redis-server是否以master状态运行,若是当前主机上的redis-server正在以master状态运行,则将vrrp_instance标记为存活状态,并分配VIP;若是当前主机上的redis-server正在以slave状态运行,则将vrrp_instance标记为错误状态。当某台主机宕机后,其余两台主机上的keepalived会将VIP切换到新的master(当前主机上的redis-server正在以master状态运行)上。三台CVM都须要安装keepalived组件。

2.在VIP方案基础之上安装keepalived组件(3台CVM都须要安装)

wget -c http://www.keepalived.org/sof...

tar zxf keepalived-1.2.19.tar.gz

cd keepalived-1.2.19

./configure --prefix=/usr/local/keepalived

make

make install
3.基本配置

(1)编译安装keepalived以后,作初始化

cp /usr/local/keepalived/sbin/keepalived /usr/sbin/

cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/

cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/

cd /etc/init.d/

chkconfig --add keepalived

chkconfig keepalived on

mkdir -p /etc/keepalived
(2)关于keepalived的配置文件

keepalived的配置文件默认是没有的,固然sample&example文件仍是有的,一般在PREFIX/etc/sample目录下。
keepalived master和backup(backups)之间不一样的是:

1.优先级的不一样,master的优先级priority的数字要高一些,我这里主redis上设置为100,从redis上设置为99;

2.global_defs段的router_id都不同,实际中能够用任意名字区分也能够用主机名区分;

3.backup的配置文件中还有一个nopreempt字段,意思是设置为非抢占模式,做用是让master优先获取到VIP,并保证VIP是在原先的master上。
● 主redis172.16.2.4上的配置:

vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {

notification_email { #指定keepalived在发生切换时须要发送email到的对象,一行一个

root@localhost

}

notification_email_from keepalived@localhost #指定发件人

smtp_server 127.0.0.1 #指定smtp服务器地址

smtp_connect_timeout 10 #指定smtp链接超时时间

router_id keepalivedha_1 #运行keepalived机器的一个标识

}

vrrp_script chk_http_port { #执行的脚本

script "redis-cli info | grep role:master >/dev/null 2>&1"

interval 1

timeout 2

fall 2

rise 1

}

vrrp_sync_group VG_1 { #监控多个网段的实例

group {

    VI_1        #实例名

}

}

vrrp_instance VI_1 {

state BACKUP

interface eth0      #设置实例绑定的网卡

#use_vmac keepalived

#vmac_xmit_base

mcast_src_ip 172.16.2.4

smtp_alert

virtual_router_id 20        #路由器标识,MASTER和BACKUP必须是一致的

priority 100        #优先级,高优先级竞选为master

advert_int 1

authentication {        #设置认证

    auth_type PASS      #认证方式

    auth_pass password      #认证密码

}

virtual_ipaddress {     #设置vip

    172.16.2.250

}

track_script {      #监测的对象

    chk_http_port

}

}
● 从redis172.16.2.2上的配置:

! Configuration File for keepalived

global_defs {

notification_email {

root@localhost

}

notification_email_from keepalived@localhost

smtp_server 127.0.0.1

smtp_connect_timeout 10

router_id keepalivedha_2

}

vrrp_script chk_http_port {

script "redis-cli info | grep role:master >/dev/null 2>&1"

interval 1

timeout 2

fall 2

rise 1

}

vrrp_sync_group VG_1 {

group {

    VI_1

}

}

vrrp_instance VI_1 {

state BACKUP

interface eth0

#use_vmac keepalived

#vmac_xmit_base

mcast_src_ip 172.16.2.2

smtp_alert

virtual_router_id 20

priority 99

advert_int 1

authentication {

    auth_type PASS

    auth_pass password

}

virtual_ipaddress {

    172.16.2.250

}

track_script {

    chk_http_port

}

    nopreempt

}
● 从redis172.16.2.15上的配置:

! Configuration File for keepalived

global_defs {

notification_email {

root@localhost

}

notification_email_from keepalived@localhost

smtp_server 127.0.0.1

smtp_connect_timeout 10

router_id keepalivedha_3

}

vrrp_script chk_http_port {

script "redis-cli info | grep role:master >/dev/null 2>&1"

interval 1

timeout 2

fall 2

rise 1

}

vrrp_sync_group VG_1 {

group {

    VI_1

}

}

vrrp_instance VI_1 {

state BACKUP

interface eth0

#use_vmac keepalived

#vmac_xmit_base

mcast_src_ip 172.16.2.15

smtp_alert

virtual_router_id 20

priority 99

advert_int 1

authentication {

    auth_type PASS

    auth_pass password

}

virtual_ipaddress {

    172.16.2.250

}

track_script {

    chk_http_port

}

    nopreempt

}
4.启动keepalived

service keepalived start

tail /var/log/messages
(1)若是在主redis上keepalived启动后日志以下图显示则表示启动成功

clipboard.png

keepalived日志输出

(2)用ip add查看VIP已经绑定到主redis上

clipboard.png

查看vip地址已经绑定

5.测试验证

模拟主redis故障时,redis的set、get和复制状况

(1)停掉主Redis(172.16.2.4)上的redis-server服务

clipboard.png

停掉主Redis(172.16.2.4)上的redis-server服务

(2)主Redis(172.16.2.4)上的VIP已经被移除

clipboard.png

主Redis(172.16.2.4)上的VIP已经被移除

(3)查看Redis(172.16.2.15)上的Redis状态已经切换成master

clipboard.png

查看Redis(172.16.2.15)上的Redis状态已经切换成master

(4)能够看出,VIP已经漂移到新的redis master(172.16.2.15)上

clipboard.png

能够看出,VIP已经漂移到新的redis-server master了

(5)从sentinel进行redis主从切换,到VIP的漂移过程是须要时间的,用ping VIP来作测试,中断时间大概须要几秒左右,以下图所示:

clipboard.png

04总结

以上经过搭建、配置、验证、测试,了解到几种redis高可用方案各有优缺点,若是网络环境可以支持组播协议,建议采用redis-sentinel+keepalived方案,这种方案配置更简单;若是网络环境不支持组播协议,可使用redis-sentinel+VIP方案;若是业务代码上可以接受在每次操做redis以前都先额外进行一次sentinel查询操做,就能够采用sentinel方案。

如下是实战过程当中总结出的最佳实践:

(1)Redis Sentinel 集群建议使用 >= 5 台机器;

(2)不一样的大业务可使用一套 Redis Sentinel 集群,代理该业务下的全部端口;

(3)根据不一样的业务划分好 Redis 端口范围;

(4)自定义脚本建议采用 Python 实现,扩展便利;

(5)自定义脚本传入参数:<service_name> <role> <comment> <from_ip> <from_port> <to_ip> <to_port>;

(6)自定义脚本须要远程 ssh 操做机器,建议使用 paramiko 库,避免重复创建 SSH 链接,消耗时间;

(7)加速 SSH 链接,建议关闭如下两个参数:
UseDNS no
GSSAPIAuthentication no

(8)微信或者邮件告警,建议 fork 一个进程,避免主进程阻塞;

(9)自动切换和故障切换,全部操做建议在 15s 之内完成。

以上几种方案都是针对单个redis实例的高可用,比较适合中小型业务的应用。若是业务数据量比较大,并发量比较高的状况下,建议搭建redis集群,好比官方redis cluster和开源的codis方案,或者使用腾讯云PAAS层redis集群方案,文档说明见:
https://cloud.tencent.com/doc...

相关文章
相关标签/搜索