生产-已解决-Redis连接数占满 报错 (error) ERR max number of clients reached

2023-10-15 04:10

本文主要是介绍生产-已解决-Redis连接数占满 报错 (error) ERR max number of clients reached,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

记一次线上Redis 报错 ERR max number of clients reached ,Redis 宕机生产事故

一、前提交代:

新需求,参与商城品牌首单价促销价格,需要在指定时间内,已购买过指定门槛品牌。
商城内关于商品价格展示接口都需校验改商品关联的促销活动是否参加 品牌首单价门槛促销,商品详情页、订单结算页、商品列表页、购物车预览页。

线上Redis 手动搭建在阿里云linux服务器内,单机版本。且此服务器部署了一台商城服务
注意这里

由于促销活动属于高并发,高流量业务,选择把门槛品牌,门槛购买时间等信息用String 数据结构存储Redis中 数据结构如下

Redis中 BD=2 
String类型  Key:promotion:brand:firstPrice:purchasedBrand:促销活动idValue:{"purchasedBrandList": [{"brandId": 9710,"brandName": "咿儿润"}],"purchasedEndTime": 1678247960000,"purchasedStartTime": 1677643160000,"buyStartTime": 1678247960000,"buyEndTime": 1678247960000,"status": 0
}

二、开发需求

开发需求期间发现前同事写的Redis 操作工具类无法选择指定DB进行存储,默认在db=0

    public <T> T get(String key, String modulePrefix, Class<T> t) {checkJedisPool(); // 检测JedisPool 是否为空 key = generateKey(key, modulePrefix);// 组装key前缀try (Jedis jedis = jedisPool.getResource()) {String valueStr = jedis.get(key);return parse(valueStr, t);}}private void checkJedisPool() {if (jedisPool == null) {throw new CacheException("jedisPool can not be null.");}}/*** 生成 key .** @param key* @param modulePrefix* @return*/private String generateKey(String key, String modulePrefix) {if (StringUtils.isBlank(key)) {throw new CacheException("key can not be null.");}if (StringUtils.isBlank(modulePrefix)) {return CacheInfo.MODULE_DEFAULT + ":" + key;}return modulePrefix + ":" + key;}

我写的工具类方法:

   public static String getString(String key, int db) {JedisPool pool = getPool();Jedis jds = null;boolean broken = false;String t = null;try {jds = pool.getResource();jds.select(db);t = jds.get(key);} catch (Exception e) {broken = true;logger.error("getString:", e);throw new RuntimeException(e);} finally {if (broken) {pool.returnBrokenResource(jds);} else if (jds != null) {pool.returnResource(jds);}}return t;}

需求开发完 测试环境,测试验证没问题,开始发版本。

三、发布新版本

我们的集群服务物理机中有一台部署的包专门提供后台管理人员使用,也就是内部人员用。一台专门跑xxl-job 定时任务。
发版平时的流程都为 先发后台机器、与定时任务机器,验证包启动无误再发 商城集群 另外两台。

发完后台机器、定时任务机器,没问题,我一如既往开始发布商城的服务器。
当发完后,半小时后,陆续有运营同学反馈管理后台某些页面加载报错,无法使用。

马上看机器日志,大量的Redis 无法连接错误报出,定时任务机器,商城机器组也开始报错。

我意识到是自己新写的业务代码有问题,马上回滚,但情急之中还是在思考,自己的写的Redis工具类是没问题的,经过了百万生产流量使用的。

把jar包构建好,准备发后台、定时任务机器,后台机器jar无法启动,提示redis 无法连接报错

 (error) ERR max number of clients reached

着急的我,还没等后台机器发完,我那时候就已经把 定时任务机器停止服务。这时候定时任务jar也无法启动,这下可急坏了,因为如果不在晚上12点把定时任务恢复的话就会导致大量定时任务无法运行,后续补任务,补数据可能出现数据重复。

这时,已经开始意识到是由于商品详情页、商品列表页、订单计算页计算价格大量请求Redis 判断是否符合门槛,导致redis过载的原因。

我想把商城机器组代码回滚到上一个版本。我停了一台商城机器,还剩一台机器对外提供商品购买,下单服务。

准备回滚代码,重新发布商城机器1,也无法启动,现在就只有一条机器在扛着流量,说实话,我自己肩膀被压得松软。

四、解决方案

自己的连接Redis查询工具类是肯定没问题,连接用完了也有归还连接词操作。
这时我仔细审查了一下前同事写的Redis工具类,发现连接用完,全都没有归还连接。。。。 这个工具类在 整个工程代码内大量使用。。。。无语死了

    public <T> T get(String key, String modulePrefix, Class<T> t) {checkJedisPool();key = generateKey(key, modulePrefix);try (Jedis jedis = jedisPool.getResource()) {String valueStr = jedis.get(key);return parse(valueStr, t);}}

我开始查资料,看Redis启动时的设置的最大连接是多少
我登入redis-cli 客户端,输入命令
在这里插入图片描述
收到的是 连接已经爆满

 (error) ERR max number of clients reached

后面临时修改,将最大连接数调大,查到资料Redis 连接数是取决于物理机最大文件可打开数

在linux 终端直接输入

 ps -ef |grep redis 
cat /proc/5129/limits
// 最大可用连接数
Max open files            10032                10032                files
redis 某时刻已经用了连接数
[root@iZwz9fp1ljg8ksssoyuo0eZ redis-5.0.5]# ll /proc/5129/fd | wc -l 
10008
[root@iZwz9fp1ljg8ksssoyuo0eZ redis-5.0.5]# 

就是说Redis 已经达到现有物理机配置的最大连接数。

1、修改物理机最大连接数后,需要重启机器。
2、商城只有这台redis宿主机在提供对外服务了,重启了就宕机了。

当时情况图:
在这里插入图片描述

晚上八点左右,流量有下降,我重启了N此终于把定时任务机器恢复了。

解决方案

现在已经确定是Redis 物理单机连接数小。
唯一办法就是重启Redis ,重置连接数。此时需要先把最后一台商城服务 停机,要不然Redis再次重启,又会被流量占满连接数。

为了尽量减低商城下单,浏览商品影响范围,选择了十一点后 停止商城服务。
1、停止所有与Redis 交互的服务。
2、重启Redis。
3、版本回退到上一个逻辑代码,重启服务。

后续优化

1、将Redis 迁移为阿里云 TariDB(企业版redis) 集群。可用连接数多,数据有保障
2、优化原有Redis 交互工具类,关闭连接。

参考资料

redis报-ERR max number of clients reached错误

解决Redis 连接池报错:ERR max number of clients reached

解决Redis 连接池报错:ERR max number of clients reached

这篇关于生产-已解决-Redis连接数占满 报错 (error) ERR max number of clients reached的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/215264

相关文章

SQL Server配置管理器无法打开的四种解决方法

《SQLServer配置管理器无法打开的四种解决方法》本文总结了SQLServer配置管理器无法打开的四种解决方法,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录方法一:桌面图标进入方法二:运行窗口进入检查版本号对照表php方法三:查找文件路径方法四:检查 S

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

XML重复查询一条Sql语句的解决方法

《XML重复查询一条Sql语句的解决方法》文章分析了XML重复查询与日志失效问题,指出因DTO缺少@Data注解导致日志无法格式化、空指针风险及参数穿透,进而引发性能灾难,解决方案为在Controll... 目录一、核心问题:从SQL重复执行到日志失效二、根因剖析:DTO断裂引发的级联故障三、解决方案:修复

IDEA Maven提示:未解析的依赖项的问题及解决

《IDEAMaven提示:未解析的依赖项的问题及解决》:本文主要介绍IDEAMaven提示:未解析的依赖项的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录IDEA Maven提示:未解析的依编程赖项例如总结IDEA Maven提示:未解析的依赖项例如

Redis的持久化之RDB和AOF机制详解

《Redis的持久化之RDB和AOF机制详解》:本文主要介绍Redis的持久化之RDB和AOF机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述RDB(Redis Database)核心原理触发方式手动触发自动触发AOF(Append-Only File)核

Redis分片集群、数据读写规则问题小结

《Redis分片集群、数据读写规则问题小结》本文介绍了Redis分片集群的原理,通过数据分片和哈希槽机制解决单机内存限制与写瓶颈问题,实现分布式存储和高并发处理,但存在通信开销大、维护复杂及对事务支持... 目录一、分片集群解android决的问题二、分片集群图解 分片集群特征如何解决的上述问题?(与哨兵模

SpringBoot连接Redis集群教程

《SpringBoot连接Redis集群教程》:本文主要介绍SpringBoot连接Redis集群教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 依赖2. 修改配置文件3. 创建RedisClusterConfig4. 测试总结1. 依赖 <de