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

相关文章

使用Redis快速实现共享Session登录的详细步骤

《使用Redis快速实现共享Session登录的详细步骤》在Web开发中,Session通常用于存储用户的会话信息,允许用户在多个页面之间保持登录状态,Redis是一个开源的高性能键值数据库,广泛用于... 目录前言实现原理:步骤:使用Redis实现共享Session登录1. 引入Redis依赖2. 配置R

shell脚本批量导出redis key-value方式

《shell脚本批量导出rediskey-value方式》为避免keys全量扫描导致Redis卡顿,可先通过dump.rdb备份文件在本地恢复,再使用scan命令渐进导出key-value,通过CN... 目录1 背景2 详细步骤2.1 本地docker启动Redis2.2 shell批量导出脚本3 附录总

批量导入txt数据到的redis过程

《批量导入txt数据到的redis过程》用户通过将Redis命令逐行写入txt文件,利用管道模式运行客户端,成功执行批量删除以Product*匹配的Key操作,提高了数据清理效率... 目录批量导入txt数据到Redisjs把redis命令按一条 一行写到txt中管道命令运行redis客户端成功了批量删除k

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

解决RocketMQ的幂等性问题

《解决RocketMQ的幂等性问题》重复消费因调用链路长、消息发送超时或消费者故障导致,通过生产者消息查询、Redis缓存及消费者唯一主键可以确保幂等性,避免重复处理,本文主要介绍了解决RocketM... 目录造成重复消费的原因解决方法生产者端消费者端代码实现造成重复消费的原因当系统的调用链路比较长的时

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

kkFileView启动报错:报错2003端口占用的问题及解决

《kkFileView启动报错:报错2003端口占用的问题及解决》kkFileView启动报错因office组件2003端口未关闭,解决:查杀占用端口的进程,终止Java进程,使用shutdown.s... 目录原因解决总结kkFileViewjavascript启动报错启动office组件失败,请检查of