当前位置 博文首页 > xzh_blog:Redis高可用架构设计以及常见问题分析
Redis的使用非常简单,只需要安装配置一下就能轻松上线,短时间不会出现什么问题,但是随着时间推移,Redis实例增多,客户端调用繁杂,真正的问题开始出现,整个关系就变得非常乱。Redis从使用角度来讲是需要像应用服务一样去治理的。
下面先看一段日常开发过程中常见的对话:
开发:Redis为啥不能访问了?
运维:刚刚服务器内存坏了,服务器自动重启了。
开发:为什么Redis延迟这么久?
运维:大哥,不要在Zset里面放几万条数据,插入排序的后果很严重啊!
开发:写进去的key呢,为什么不见了?
运维:你的Redis内存超过最大大小了,不常用的key都丢了呀!
开发:刚刚为啥读取全部失败了?
运维:刚刚网络临时中断了一下,slave全同步了,在全同步完成之前,slave的读取全部失败。
开发:我刚刚想到一个好方案,我需要800GB的Redis,什么时候能准备好呢?
运维:大哥,我们线上的服务器最大也就256GB,别玩这么大好吗?
一些常见策略以及其弊端:
1.单机不是不安全吗?那么就开启主从+Keepalived,用虚IP地址在master和 slave两边漂移,master挂了直接切换到slave。
主从+Keepalived 的方案,本来是个很好的方案,但是忽略了主数据节点挂掉的情况。Redis的单进程、单线程设计是其简单和稳定的基石,只要不是服务器发生了故障,在一般情况下是不会挂的。但同时,单进程、单线程的设计会导致Redis接收到复杂指令时会忙于计算而停止响应,可能就因为一个Zset或者keys之类的指令,Redis计算时间稍长,Keepalived就认为其停止了响应,直接更改虚IP的指向,然后做一次主从切换。过不了多久,Zset和 keys之类的指令又会从客户端发送过来,于是从机上又开始堵塞,Keepalived就一直在主从机之间不断地切换IP。终于主节点和从节点都堵了,Keepalived发现后,居然直接将虚IP释放了,然后所有的客户端都无法连接Redis了,只能等运维到线上手工绑定才行。
2.数据放内存不是不安全吗?可以开启数据落盘,根据业务需要决定落盘规则,有AOF的,也有RDB的。
数据落盘也引起了很大的问题,RDB属于非阻塞式的持久化,它会创建一个子进程来专门把内存中的数据写入RDB文件里,同时主进程可以处理来自客户端的命令请求。但子进程内的数据相当于是父进程的一个拷贝,这相当于两个相同大小的Redis进程在系统上运行,会造成内存使用率的大幅增加。如果在服务器内存本身就比较紧张的情况下再进行RDB配置,内存占用率就会很容易达到100%,继而开启虚拟内存和进行磁盘交换,然后整个Redis的服务性能就直线下降了。
另外,Zset、发布订阅、消息队列、Redis的各种功能不断被介绍,开发者们也在利用这些特性,开发各种应用,但从来没想过这么一个小小的Redis 有这么多新奇的功能,它的缺点在什么地方,什么样的场景是不合适用的?这时Redis在大部分的开发者手上就是像是一把锤子,看什么都是钉子,随时都一锤了事。同时也会渐渐地淡忘了开发的一些细节点和规范,因为用它解决性能的问题是那么轻松简单,于是一些基于Redis的新奇功能就接连不断地出现了:基于Redis的分布式锁、日志系统、消息队列、数据清洗,等等,各种各样的功能不断上线使用,从而引发了各种各样的问题。这时候原来那个救火神器就会变成四处点火的神器,Redis堵塞、网卡打爆、连接数爆表等问题层出不穷,经过这么多折腾,Redis终于也变成了大家的噩梦了。
总结以下几点需要解决:
具体方案: