生产-已解决-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

相关文章

如何解决mmcv无法安装或安装之后报错问题

《如何解决mmcv无法安装或安装之后报错问题》:本文主要介绍如何解决mmcv无法安装或安装之后报错问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mmcv无法安装或安装之后报错问题1.当我们运行YOwww.chinasem.cnLO时遇到2.找到下图所示这里3.

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

Redis分片集群的实现

《Redis分片集群的实现》Redis分片集群是一种将Redis数据库分散到多个节点上的方式,以提供更高的性能和可伸缩性,本文主要介绍了Redis分片集群的实现,具有一定的参考价值,感兴趣的可以了解一... 目录1. Redis Cluster的核心概念哈希槽(Hash Slots)主从复制与故障转移2.

Feign Client超时时间设置不生效的解决方法

《FeignClient超时时间设置不生效的解决方法》这篇文章主要为大家详细介绍了FeignClient超时时间设置不生效的原因与解决方法,具有一定的的参考价值,希望对大家有一定的帮助... 在使用Feign Client时,可以通过两种方式来设置超时时间:1.针对整个Feign Client设置超时时间

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3

mysql出现ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的解决方法

《mysql出现ERROR2003(HY000):Can‘tconnecttoMySQLserveron‘localhost‘(10061)的解决方法》本文主要介绍了mysql出现... 目录前言:第一步:第二步:第三步:总结:前言:当你想通过命令窗口想打开mysql时候发现提http://www.cpp

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

springboot报错Invalid bound statement (not found)的解决

《springboot报错Invalidboundstatement(notfound)的解决》本文主要介绍了springboot报错Invalidboundstatement(not... 目录一. 问题描述二.解决问题三. 添加配置项 四.其他的解决方案4.1 Mapper 接口与 XML 文件不匹配

Redis 中的热点键和数据倾斜示例详解

《Redis中的热点键和数据倾斜示例详解》热点键是指在Redis中被频繁访问的特定键,这些键由于其高访问频率,可能导致Redis服务器的性能问题,尤其是在高并发场景下,本文给大家介绍Redis中的热... 目录Redis 中的热点键和数据倾斜热点键(Hot Key)定义特点应对策略示例数据倾斜(Data S

mysql如何查看当前连接数

《mysql如何查看当前连接数》:本文主要介绍mysql如何查看当前连接数问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql查看当前连接数查看mysql数据库允许最大连接数总结mysql查看当前连接数查看当前连接数SHOW STATUS LIKE