云数据库Redis版,主从热备高可用方案怎么实现?

引言

高可用(High Available)是线上生产环境所必不可少的重要条件,阿里云数据库Redis版作为一款成熟稳定的数据库产品,针对Redis的特性也支持高可用,本文将介绍云Redis是如何实现这一方案。

架构

目前云Redis有主从版和集群版两种架构,本次主要针对主从版做HA的解析,集群版HA只在最后切换VIP指向时稍有不同,但均可保证高可用性。

下图为主从版架构:

云数据库Redis版,主从热备高可用方案怎么实现?

由图可知,云Redis实例有主备两个节点,平时只有Master提供服务,Slave只做热备不提供访问,Slave通过slaveof命令不断从Master接收数据,保证Master宕机时云Redis仍可提供服务。

每一个云Redis实例都会分配一个VIP并与DNS绑定,VIP经过SLB后直接访问Master不再有其他中间层,访问Redis的链路为DNS-->VIP-->SLB-->REDIS(MASTER)。

HA模块

HA作为一个独立的系统模块,远程探测云Redis的健康状况,当发生实例不可用时及时主备切换以保证服务质量。

健康检查

健康检查的逻辑很简单,通过客户端连接Redis并发送PING命令,如果返回PONG则说明Redis健康,其他情况则说明Redis异常,检测逻辑用伪代码来说明:

try:

client = Redis(ip, port, connection_timeout, socket_timeout) //指定要连接Redis的ip:port(这里的ip:port即可以是VIP:VPORT也可以是Master或Slave的物理ip:port,HA会有多维度的探测),并设置超时时间

client.connect() //尝试连接Redis,如果连接失败或超时则会抛出异常

res = client.ping() //向Redis发送ping命令,结果为PONG说明Redis健康,返回OK;结果非PONG或超时则会抛出异常

if res == PONG: return OK

except: //处理异常情况,若异常在预先定义的错误内,说明Redis真的异常,返回ERROR,HA会做下一步切换动作

if e.message in ERRORS: return ERROR else: return OK

需要HA真正做切换的异常情况有以下几种:

/* 指定ip地址的机器不能找到(也就是说从当前机器不存在到指定ip路由),或者是该ip存在,但找不到指定的端口进行监听,这时Redis所在主机可能宕机或是进程挂掉 */"Connection refused"

/* 服务器的并发连接数超过了其承载量,服务器会将其中一些连接主动Down掉 */"Connection reset"

/* 连接超时,目前设置为18秒 */

"connect timed out"

/* 读取数据超时,目前设置为2分钟 */

"Read timed out"

/* Redis正在加载数据 */

"LOADING Redis is loading the dataset in memory"

/* 访问的Redis是Slave */

"READONLY You can't write against a read only slave"

关于为何将读超时设置为2分钟这么久呢,这是我们在日常运维处理各种问题时,根据总结出来的经验设置的一个相对合理的大小。

在一开始时读超时的时间设置的和连接超时同样为18秒,结果线上经常会有HA发生主备切换,这是因为Redis处理客户端命令的线程只有一个,当在处理一些耗时操作比如FLUSHALL、KEYS等命令时,执行时间可达数十秒甚至几分钟,此时Redis处于"假死"状态造成误切换。经测试,清空64G的数据大约需要2分钟的时间(目前主从版云Redis最大实例规格即为64G),故将读超时设置为2分钟。

单纯调整超时时间并不是我们的最终方案,这里仍在改进,比如增加一个状态监测端口,新开一个状态线程来探测Redis活性等,欢迎大家集思广益提供优质解决方案。

主备切换前准备工作

当健康检查发现Redis出现不可用情况时就要准备进行主备切换,在主备切换真正执行前需要额外做一些工作:

通过VIP检查Redis健康状态if VIP不健康:

检查Slave状态 if Slave健康:

再次检查VIP状态 if VIP健康:

无需主备切换 else:

执行主备切换 else:

Slave不健康无法切换else:

无需主备切换

在执行切换前要检查Slave状态以确保切换后实例是可服务的,否则即使切换也是无效的,比如两台主机都宕机这种极端情况。

同时对VPC类型的实例做了特殊处理,因为我们是没有办法访问用户自定义网络的VIP的,这时需要把对VIP的健康检查换成对Master的健康检查。

执行主备切换

当Redis出现不可用且满足切换条件时,真正开始执行主备切换动作。同时切换动作也支持主动的任务切换和被动的故障切换,两者主要区别在是否需要Slave等待Master达到同步状态,以下对主备切换做详细说明:

1. 额外再次检查一次Master状态

if Master健康:

if 故障切换:

无需切换,返回成功

else:

a. 设置Master为readONLY只读状态

b. 通过info replication命令检查主备同步状态,也即master_repl_offset是否等于Slave的offset

if 若超时仍未达到一致状态:

重置Master为readwrite可读写状态,并返回异常

else:

日志记录此时Master无法连接2. 切换VIP指向Slaveif 切换失败:

记录日志并返回异常3. 更新主备元信息4. 向Slave发送slaveof no one命令,使其升级为新的Master5. 尝试向原Master发送slaveof命令,使其降级为新的Slave

此时原Master可能已经宕机,故不做失败处理,仅记录日志

通过以上方案,云数据库Redis版SLA可以达到99.99%,仅在主从都发生宕机的极端情况无法服务。

结束

本文介绍了云数据Redis版HA方案,通过主从双机热备来保证服务高可用,健康检查出现异常时及时进行主备切换,有效保障业务运行。

结尾顺便打个硬广,即日起购买阿里云数据库Redis版(首台)3年5折、1年6折、按月7折啦,赶快点击购买吧:https://m.aliyun.com/markets/aliyun/act/redissaleoff?spm=5176.8112568.483450.6.o85c4v

相关推荐