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

文章讲述了在上线新功能后,由于Redis单机版本达到最大客户端连接数引发的生产事故。问题源于旧的Redis操作工具类未正确归还连接,以及系统在高并发场景下对Redis的大量请求。解决方案包括增大Redis的最大连接数,临时迁移至阿里云TariDB集群,并优化Redis交互工具类,确保连接关闭。

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

一、前提交代:

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

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

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

Redis中 BD=2 
String类型  Key:promotion:brand:firstPrice:purchasedBrand:促销活动id

Value:{
   
   
    "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 
<think>我们正在处理的是Redis集群构建过程中出现的连接数达到上限的错误:`ERR max number of clients + cluster connections reached`。这个错误通常发生在创建集群的过程中,因为Redis集群的创建需要同时建立多个连接(包括节点间的内部连接),如果配置的最大连接数不足,就会导致这个错误。 根据引用[3]和[4],我们知道Redis有两个相关的配置参数: - `maxclients`:设置客户端最大连接数(包括普通客户端和集群连接) - `cluster-connections`(在Redis集群中,节点间需要建立集群总线连接,这些连接也占用连接数) 在Redis 7.4.2中,集群节点之间需要建立连接,这些连接会占用客户端的连接数。因此,当配置的最大连接数不足以支持集群创建时,就会报错。 ### 解决方案步骤: #### 1. **临时提高最大连接数(推荐)** 在创建集群之前,我们可以通过Redis命令临时提高最大连接数,创建完成后再恢复(如果需要)。这样无需重启服务,避免影响现有连接(如果有的话)。 登录到每个节点,执行以下命令: ```bash redis-cli -p 7000 config set maxclients 10000 # 设置一个足够大的值,比如10000 ``` 注意:这个设置是临时的,重启后失效。如果需要永久生效,需要修改配置文件并重启。 #### 2. **永久修改最大连接数** 修改每个节点的`redis.conf`配置文件,增加以下配置: ```conf maxclients 10000 # 设置一个足够大的值 ``` 然后重启Redis服务使配置生效: ```bash redis-cli -p 7000 shutdown redis-server /path/to/redis_7000.conf ``` #### 3. **检查并关闭未使用的连接** 如果问题是由于程序中没有正确关闭连接导致的(如引用[5]所述),我们需要检查代码中是否在使用Redis后正确关闭了连接。例如,在使用Jedis客户端时,确保在finally块中调用`jedis.close()`。 #### 4. **检查集群节点间的网络连接** 确保所有节点之间的端口都是开放的,包括客户端端口(如7000)和集群总线端口(客户端端口+10000,即17000)。如果防火墙阻止了这些端口的通信,也会导致连接失败,从而可能引发连接数累积。 #### 5. **验证集群创建** 在调整最大连接数后,重新执行集群创建命令: ```bash redis-cli --cluster create \ 192.2.23.11:7000 \ 192.2.23.11:7001 \ 192.2.23.11:7002 \ 192.2.23.11:7003 \ 192.2.23.11:7004 \ 192.2.23.11:7005 \ --cluster-replicas 1 ``` #### 6. **监控连接数** 在集群创建过程中,可以监控连接数的使用情况,以便确认问题是否解决: ```bash redis-cli -p 7000 info clients ``` 输出中关注: ``` connected_clients: [当前客户端连接数] cluster_connections: [集群内部连接数] maxclients: [允许的最大连接数] ``` ### 注意事项: - 在创建集群时,每个节点都需要与其他节点建立连接。对于6个节点的集群(3主3从),每个节点会与其他5个节点建立集群总线连接(每个连接占用一个客户端连接数)。因此,至少需要为每个节点预留6个连接(1个用于客户端命令,5个用于集群内部通信)。如果同时有多个客户端连接,则可能需要更多。 - 默认的`maxclients`是10000,通常足够。但如果之前被调低,或者存在大量连接未释放,就可能出现此错误。 ### 常见问题排查: - 如果调整后仍然出现连接数不足,请检查是否有连接泄漏(即连接未关闭)。可以使用`client list`命令查看连接来源,并分析是否需要关闭。 - 确保没有其他应用程序在大量使用Redis连接。 ### 引用说明: - 引用[3][4][5]提供了关于连接数不足错误的背景和解决方案,包括如何查看当前连接数、设置最大连接数以及检查代码中未关闭的连接[^3][^4][^5]。 --- §§相关问题§§ 1. 如何监控 Redis 集群的连接数使用情况? 2. Redis 集群总线端口的作用是什么? 3. 除了连接数不足,还有哪些原因会导致 Redis 集群创建失败? 4. 如何永久修改 Redis 的最大连接数配置?</think>### 解决 Redis 7.4.2 集群节点连接数超限错误:`ERR max number of clients + cluster connections reached` #### 错误原因分析 1. **连接数超限**:Redis 默认最大连接数 `maxclients=10000`,但集群创建过程需要同时建立多个内部连接(节点间通信 + 集群总线) 2. **配置未生效**:修改 `redis.conf` 后未重启服务,导致新配置未加载(常见陷阱)[^2] 3. **资源泄漏**:未关闭的闲置连接持续占用资源(如创建集群失败后残留连接) 4. **集群规模**:6节点集群创建时至少需要 12+ 连接(每节点需连其他5节点) --- ### 完整解决方案(逐步操作) #### 步骤1:立即释放连接(临时解决) ```bash # 登录问题节点 redis-cli -h 192.2.23.11 -p 7000 # 强制断开所有客户端连接(慎用!会影响业务) > CLIENT KILL TYPE normal # 断开普通客户端 > CLIENT KILL TYPE pubsub # 断开发布订阅连接 > CLIENT KILL TYPE replica # 断开副本连接 ``` #### 步骤2:永久修改连接数配置 在 **每个节点** 的 `redis.conf` 中添加: ```conf maxclients 20000 # 提升至2万连接 cluster-connections 100 # 显式设置集群总线连接数 ``` > 📌 *重要*:Redis 7.x 新增 `cluster-connections` 参数控制集群内部连接池[^3] #### 步骤3:重启所有节点使配置生效 ```bash # 依次重启每个节点 redis-cli -h 192.2.23.11 -p 7000 shutdown redis-server /etc/redis/7000.conf # 指定配置文件绝对路径 ``` > ✅ 验证命令:`redis-cli -p 7000 config get maxclients` 应返回 `20000` #### 步骤4:创建集群时指定连接参数 ```bash redis-cli --cluster create \ 192.2.23.11:7000 192.2.23.11:7001 ... \ --cluster-replicas 1 \ --cluster-connections 50 # 显式控制创建过程的连接数 ``` #### 步骤5:验证连接状态 ```bash redis-cli -p 7000 info clients ``` 预期输出: ``` connected_clients: 6 # 普通客户端连接 cluster_connections: 5 # 集群内部连接(节点数-1) maxclients: 20000 # 确认新配置生效 client_recent_max_input_buffer: 8 # 输入缓冲区正常 ``` --- ### 深度优化建议 1. **连接池管理** 在应用代码中使用连接池(如Jedis/JedisCluster),确保每次操作后关闭连接: ```java // Java示例(Jedis) try (Jedis jedis = pool.getResource()) { jedis.set("key", "value"); // 自动关闭连接 } ``` 2. **监控关键指标** ```bash watch -n 1 "redis-cli -p 7000 info clients | grep -E 'connected|max'" ``` 当 `connected_clients + cluster_connections > 0.8 * maxclients` 时发出告警 3. **内核参数调优**(Linux系统) ```bash # 增加系统级连接限制 echo "fs.file-max=65535" >> /etc/sysctl.conf sysctl -p ``` --- ### 故障排查矩阵 | 现象 | 检查命令 | 解决方案 | |------|----------|----------| | 连接数持续增长 | `redis-cli client list` | 检查闲置连接(`idle>300s`)并优化代码 | | 集群握手失败 | `redis-cli cluster info` | 确认 `cluster-connections` 配置一致 | | 创建过程卡死 | `netstat -tulnp | grep 17000` | 检查集群总线端口(7000+10000)是否开放 | --- ### 关键配置说明 | 参数 | 默认值 | 建议值 | 作用 | |------|--------|--------|------| | `maxclients` | 10000 | 20000 | 总连接数上限 | | `cluster-connections` | 无 | 节点数×2 | 集群内部连接池大小 | | `tcp-keepalive` | 300 | 60 | 快速回收失效连接 | | `timeout` | 0 | 300 | 自动关闭闲置连接() | > 通过上述配置调整,可有效避免 `ERR max number of clients + cluster connections reached` 错误[^3][^4][^5]。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

真香号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值