云数据库Redis版主从热备高可用方案

引言

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

架构

目前云Redis有主从版和集群版两种架构,本次主要针对主从版做HA的解析。

下图为主从版架构:

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

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

在底层原理上集群版HA与主从版基本相同,只是实现时稍有差异,因为链路上在VIP和后端REDIS之间多了一层proxy的路由转发,所以在做后端rs切换时无需更改VIP指向,而是去更新proxy的路由表。

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"
/ 连接超时 /
"connect timed out"
/ 读取数据超时 /
"Read timed out"
/ Redis正在加载数据 /
"LOADING Redis is loading the dataset in memory"
/ 访问的Redis是Slave /
"READONLY You can't write against a read only slave"

健康检查升级方案

Redis工作在单线程模式下,接收到的所有命令都会进入队列串行处理,当遇到一些耗时命令如flushall、keys * 等,很容易造成客户端等待超时。此时如果超时时间设置不准确的话,HA远程探测就容易误判Redis不健康,而且单单一个PING命令也不能完全获得Redis的进程状态。

Redis自带的HA方案Sentinel就是依赖PING来做健康检查,通过配置sentinel down-after-milliseconds mymaster,来决定当PING超时多久没有收到回复就认为Redis宕机,但是这样做有一定风险,比如一个64G的实例flushall清空数据大概为2分钟,如果超时时间设置为60s那么很容易造成误判。

为了解决这个问题,我们对Redis内核进行了改造,增加了一个状态线程来专门为HA提供健康检查的服务。同时也新增了一个状态端口,状态线程监听这个端口,HA探测时也通过这个端口与Redis进行交互,不会对Redis服务主线程造成影响。通过新增的状态线程也可以做很多额外的探测,例如读写性能、磁盘IO情况等。

我们把Redis主线程监听的端口叫做redis_port,状态线程监听的端口叫做status_port新的健康检查逻辑如下:

try:
    client = Redis(ip, status_port, connection_timeout, socket_timeout)
    //这里要连接的端口为状态端口status_port
    client.connect()
    //尝试连接Redis,如果连接失败或超时则会抛出异常
    res = client.health_check()
    //向Redis发送定制的健康检查命令,结果为True说明Redis健康,返回OK;否则抛出异常
    if res == True:
        return OK
except:
    //处理异常情况,若异常在预先定义的错误内,说明Redis真的异常,返回ERROR,HA会做下一步切换动作
    if e.message in ERRORS:
        return ERROR
    else:
        return OK

主备切换前准备工作

当健康检查发现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指向Slave
if 切换失败:
    记录日志并返回异常
3. 更新主备元信息
4. 向Slave发送slaveof no one命令,使其升级为新的Master
5. 尝试向原Master发送slaveof命令,使其降级为新的Slave
    此时原Master可能已经宕机,故不做失败处理,仅记录日志

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

切换场景

宕机或是进程异常退出是最为严重的情况,此时HA远程探测到redis无法连接会立即切换,实际测试整个过程可以实现秒级切换。

在主备切换后原来的Master变成了Slave,为了保障云Redis依旧高可用,会有另外的组件来探测Slave的可用性,当备库发生宕机时触发备库重搭功能,时刻保证主从双节点热备。

与Redis-Sentinel对比

Redis2.8版本自带Redis-Sentinel的高可用解决方案,通过一个或多个Sentinel实例组成的Sentinel系统来监测Master和Slave,具体方案有很多资料可以查阅不再赘述。
我们在生产环境中并没有采用自带的Sentinel,主要是出于以下几点考虑:

1. 虽然Sentinel本身也是一个Redis进程,但是运行在特殊模式下,实际维护Sentinel就需要额外配置一个角色,增加了系统的复杂度。
2. Sentinel自身的高可用问题,如果是单点Sentinel其本身也具有故障无法转移的风险,那么就要搭建Sentinel集群,这无形中也增加了管理成本。
3. Sentinel本身是有状态的,需要在启动时加载配置文件来获取Master信息,如果搭建分布式的Sentinel集群,动态增删改也会带来一致性问题,这对云上弹性资源并不适用,无法应对实例的创建、删除、变配、迁移等动作。
4. Sentinel的健康检查并不够灵活,上一节已经讲过单纯通过PING来检查无法应对flushall、keys * 等耗时命令,我们的健康检查升级方案会更好的应对云上复杂环境。

由于上述问题Sentinel不能作为一个统一的HA系统来管理所有云Redis资源,而为每个云Redis单独搭建一套Sentinel系统又会造成资源浪费和管理复杂度,基于此我们开发了这一套适用于云Redis的HA系统。

结束

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

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

阿里云数据库Redis团队诚邀加入:
https://job.alibaba.com/zhaopin/position_detail.htm?spm=0.0.0.0.l7roxQ&positionId=26437

时间: 2024-11-18 23:09:37

云数据库Redis版主从热备高可用方案的相关文章

云数据库Redis版备份恢复解决方案上线,数据可靠性全面升级!

阿里云云数据库Redis版致力于为用户提供稳定可靠.性能卓越.可弹性伸缩的数据库服务,并提供全套的容灾切换.故障迁移.在线扩容.性能优化的数据库解决方案. 云数据库Redis版采用双击热备的架构保证服务高可用,并且提供了持久化机制来保证数据可靠性.但是随着越来越多的业务开始使用Redis作为最终的持久化存储引擎,用户对于数据可靠性就提出了更高的需求.经过一段时间的打磨,我们正式推出了Redis备份恢复解决方案,全面的升级云数据库Redis的数据可靠性.   1.     数据备份一键式操作 由于

云数据库redis版的性能测试

测试环境和命令: 阿里云VPC环境, 4 x (1核, 2G ECS) 用于运行codis proxy codis proxy后端slot均衡的接2个或4个阿里云redis实例 内网SLB连接4个codis proxy 只单纯测试单条读写, 命令如下: ./redis-benchmark -a <auth-passwd> -h <slb-addr> -c 64 -n 500000 -P 100 -r 1048576 -d 256 -t get,set 测试结果: Spec. Val

一分钟了解阿里云产品:云数据库Redis版

一.             概述   阿里云发布了很多款产品,几天让我们来一起了解下云数据库Redis版(AliCloudDB for Redis)吧.     什么是云数据库Redis呢?   运输库Redis是兼容开源Redis协议的Key-Value类型在线存储服务.云数据库Redis版支持字符串.链表.集合.有序集合.哈希表等多种数据类型,及事务(Transactions).消息订阅与发布(Pub/Sub)等高级功能.通过内存+硬盘的存储方式,云数据库Redis版在提供高速数据读写能力

云数据库Redis版读写分离规格,极大满足读多写少场景,超凡性价比

了解更多关于云数据库Redis版,请点击此处 云数据库Redis版读写分离规格技术解读,详情请点击此处

云数据库Redis版的开源之路

本文整理自2017云栖大会-上海峰会中阿里云高级技术专家蔡松露的分享讲义,讲义主要介绍了ApsaraCache开源的内容,分支技术特典VS社区开源版本,云Redis产品系列,与一些经典案例与产品规划.

redis 学习笔记(4)-HA高可用方案Sentinel配置

上一节中介绍了master-slave模式,在最小配置:master.slave各一个节点的情况下,不管是master还是slave down掉一个,"完整的"读/写功能都将受影响,这在生产环境中显然不能接受.幸好redis提供了sentinel(哨兵)机制,通过sentinel模式启动redis后,自动监控master/slave的运行状态,基本原理是:心跳机制+投票裁决 每个sentinel会向其它sentinal.master.slave定时发送消息,以确认对方是否"活

云数据库Redis游戏行业解决方案解读

Redis作为最流行的Key-value数据库,近年来在游戏行业有着广泛的应用.阿里云云数据库Redis于2015年正式商业化,提供了全套的容灾切换.故障迁移.在线扩容.性能优化的数据库解决方案,同时也对游戏行业推出了许多便捷的功能. 下面我就来解读云数据库Redis版针对游戏行业的特性 1.数据持久化,保证数据高可靠性 传统的数据库架构往往是采用关系型数据库存储数据(如:MySQL),在MySQL前端利用缓存来存储访问量极高的数据(如:Redis),整体提升系统性能. 然而有时游戏公司为了快速

阿里云云数据库Redis版降价35%  分享技术红利

6月10日,在云栖大会·上海峰会,阿里云宣布将下调云数据库Redis版-集群版价格,最高降幅35%,摩尔定律在云计算领域再获验证.经过一年内的连续两次调价后,阿里云云数据库Redis版的价格已累计下降超过66%. 阿里云方面表示:"技术进步是存储成本得以快速下降的原因,我们希望能够将技术红利分享给客户."据悉,此次价格调整已在10日中午生效.具体调价内容见下图: "云数据库本身的低成本和连续多次降价,已大幅降低了数据库的成本.这将对传统的数据库模式产生巨大冲击,吸引更多企业采

云数据库Redis单节点集群规格,完美适配超大型纯缓存业务

了解更多关于云数据库Redis版,请点击此处