Redis连接数问题
1. 定义
指因为各种原因,程序对Redis的连接数激增,超过Redis服务器能够承受的上线,从而程序无法正常访问Redis进而引发功能异常的问题。Redis连接数问题并不常见,但是发生之后造成的Redis暂时不可用会影响正常功能,至少系统性能急剧下降,影响较大。自2020年来,贝壳线上服务出现过4次Redis连接数问题
在本章节,希望能够带大家了解Redis连接数问题的现象和解法。
2. 背景知识
Redis原生支持长短连接,但与我们使用数据库类似,大多数Redis客户端/中间件都使用了连接池来管理对Redis服务器的连接,从而达到连接复用、提高IO效率的效果(连接池的概念与作用不再赘述)。无论是Jedis还是Lettuce,都默认支持了连接池的配置,池中连接都是长连接。
通常我们使用Redis可能有几种场景:
- 用作缓存,若丢失,程序可以自动或手动重建,不影响业务正确性,但极有可能影响性能;
- 用作存储,若丢失即是业务数据的丢失,较难恢复,一般为不重要的数据,业务上应有预案;
- 用作分布式锁,若丢失则可能造成数据一致性问题;
- 用作阻塞队列,若丢失则可能造成业务数据的丢失,需要有相应的校验与补偿措施。
提倡使用1、3,不提倡使用2、4。特别是4阻塞队列,虽不禁止,但对Redis连接占用极为严重,应作为最后之举,之前应该寻求使用其他消息队列中间件、内存处理等方案。
3. 问题处理
3.1 如何感知问题
生产Redis强烈建议不要用第三发工具连接上。目前公司内针对Redis的监控报警能够比较及时的反应连接数问题,形如下:
日志也有所反应:
OP会看到如下趋势图:

Redis连接数问题发生时,除了Redis本身的报警外,往往还伴随着数据库压力上升(因为缓存失效)、应用接口频繁报错等现象。
3.2 常见原因
- 生产容量规划不合理,较多数量的应用机器但没有申请匹配容量的Redis服务器;
- 正常发布时,旧节点摘流后一段时间内,其连接池尚未完全断开,而同时新的节点又启动开始连接,使得Redis服务器面对了成倍的连接请求;
- 碰到某种连接异常时,程序反复重试,连接激增;
- 过度使用阻塞队列;
- 使用第三方工具连上Redis,工具本身设计不完善(例如scan所有key)引起生产问题。
3.3 如何止损
问题发生时首先可以考虑采取如下措施进行止损:
- 若判断为上述第1、2种原因,首先考虑应用缩容
- 若判断为上述第3、4种原因,首先考虑重启应用(且避免进入原因2,参照下方解决方案2)
- 若判断为上述第5种原因,立即停止工具的使用
- 与此同时,服务器端请OP帮忙清理连接、Redis扩容、切从等
3.4 长效解决方案
- 新功能上线、新活动应对时,合理规划生产容量,一定数量的应用机器应该匹配相应容量的Redis服务器
- 正常发布时,旧节点摘流、新节点启动两者的时间间隔需要适当控制,不宜太快,以免依赖资源打满
- 应用代码中谨慎重试
- 慎重将Redis用作阻塞队列,应作为最后之举,之前应该寻求使用其他消息队列中间件、内存处理等方案
- 禁止使用第三方工具连上Redis