jinfeng_wang

G-G-S,D-D-U!

BlogJava 首页 新随笔 联系 聚合 管理
  400 Posts :: 0 Stories :: 296 Comments :: 0 Trackbacks
http://www.tuicool.com/articles/beYZfi7

引言

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

架构

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

下图为主从版架构:

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

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

结束

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

posted on 2016-12-14 16:27 jinfeng_wang 阅读(119) 评论(0)  编辑  收藏 所属分类: 2016-REDIS

只有注册用户登录后才能发表评论。


网站导航: