Redis连接与会话管理
笔记哥 /
05-24 /
11点赞 /
0评论 /
110阅读
# 序:文由
- 排查问题,发现微服务因 `ERR max number of clients reached` (**已达到客户端的最大数量**) redis异常,而导致服务在健康检测时未通过,进而导致高频宕机。
# 概述:Redis 连接与会话管理
## Redis 连接会话的原理
- redis通过监听一个TCP端口或socket的方式接收来自客户端的连接,当与客户端**建立连接后**,redis内部会进行如下操作:
>
>
> (1)客户端socket会被设置为非阻塞模式,因为redis在网络时间处理上采用的是非阻塞多路复用模型;
>
> (2)为这个socket设置TCP\_NODELAY属性,禁用Nagle算法;
>
> (3)创建一个可读的文件事件用于监听这个客户端socket的数据发送。
>
# 常用功能与指令
## 连接操作类
### 查看连接总数 : `info clients`
```shell
> info clients
# Clients
connected_clients:95
client_recent_max_input_buffer:2
client_recent_max_output_buffer:0
blocked_clients:0
rx_controlled_clients:0
total_real_rx_controlled:0
total_tx_controlled:0
total_rx_controlled:824214
proxy_header_error:0
```
### 查看连接详情列表 : `client list`
- `client list` : 命令用于返回所有连接到服务器的客户端信息和统计数据。
>
>
> http://www.redis.cn/commands/client-list.html
>
```shell
client list
```

- 返回值
>
>
> `bulk-string-reply`: 一个独特的字符串。具体格式:
>
>
>
> >
> >
> > 每个已连接客户端对应一行(以 LF 分割)
> >
> > 每行字符串由一系列 属性=值(property=value) 形式的域组成,每个域之间以空格分开。
> >
> > 各字段的含义::
> >
>
>
```txt
id: 唯一的64位的客户端ID(Redis 2.8.12加入)。
addr: 客户端的地址和端口
fd: 套接字所使用的文件描述符
age: 以秒计算的已连接时长
idle: 以秒计算的空闲时长
flags: 客户端 flag
db: 该客户端正在使用的数据库 ID
sub: 已订阅频道的数量
psub: 已订阅模式的数量
multi: 在事务中被执行的命令数量
qbuf: 查询缓冲区的长度(字节为单位, 0 表示没有分配查询缓冲区)
qbuf-free: 查询缓冲区剩余空间的长度(字节为单位, 0 表示没有剩余空间)
obl: 输出缓冲区的长度(字节为单位, 0 表示没有分配输出缓冲区)
oll: 输出列表包含的对象数量(当输出缓冲区没有剩余空间时,命令回复会以字符串对象的形式被入队到这个队列里)
omem: 输出缓冲区和输出列表占用的内存总量
events: 文件描述符事件
cmd: 最近一次执行的命令
```
### 设置当前连接点redis的名称 : `CLIENT SETNAME`
```shell
CLIENT SETNAME
```
### 查看当前连接的名称 : `CLIENT GETNAME`
```shell
CLIENT GETNAME
```
### 杀死指定连接 : `CLIENT KILL {ip}:{port}`
```csharp
CLIENT KILL {ip}:{port}
```
## 连接配置类
### 查看/设置连接的默认超时自动断连时间(空闲超时时间) : `config [get|set] timeout [{second}]`
- 查看连接的默认超时自动断连时间(空闲超时时间)
>
>
> 默认值 = 0
>
```shell
> config get timeout
0
```
- 设置连接的默认超时自动断连时间(空闲超时时间)
>
>
> 单位:秒钟
>
```shell
config set timeout 600
```
### 查询/设置允许的最大连接数 : `config get maxclients`
- 查询允许的最大连接数
```shell
config get maxclients
```
- 设置允许的最大连接数
>
>
> 方法1:在2.6之后版本,可以修改最大连接数配置,默认`10000`,可以在`redis.conf`配置文件中修改
>
```shell
...
# maxclients 10000
...
```
>
>
> 方法2: `config set maxclients num` 可以设置redis允许的最大连接数
>
```shell
127.0.0.1:6379> CONFIG set maxclients 10
OK
127.0.0.1:6379>
```
>
>
> 方法3:启动`redis.service`服务时加参数`--maxclients 100000`来设置最大连接数限制
>
```shell
redis-server --maxclients 100000 -f /etc/redis.conf
```
# FAQ for Redis 连接与会话管理
## Q: 连接过多,乃至报`ERR max number of clients reached`(Redis客户端连接数已达到最大限制)?
- 问题分析
>
> - `redis maxclients`
>
>
>
>
> >
> >
> > `redis maxclients` 是redis server的重要配置,它决定了**客户端的最大连接数量**、**最大客户端连接数量**。
> >
> > 由于redis不区分连接是客户端连接、还是内部打开文件、或者和slave连接等。所以,`maxclients`最小存在32个连接数,如果超过了设置的maxclients,redis会给新的连接发送"`max number of clients reached`",并**关闭连接**。
> >
>
>
>
> - 硬编码限制
>
>
>
>
> >
> >
> > 在Redis 2.4中,可以同时处理的最大客户端数量存在**硬编码限制**。
> >
> > 在Redis 2.6中,此限制是**动态**的:默认情况下,它设置为10000个客户端,除非`Redis.conf`中的`maxclients`指令另有说明。
> >
>
>
>
> - 原因分析
>
>
>
>
> >
> >
> > 绝大部分原因:由于客户端很多**空闲连接**都没有被及时释放掉,从而导致`connected_clients`非常高
> >
> > 其他可能:`maxclients`设置的太少了
> >
> > 还有可能:软硬件存在限制
> >
>
>
- 解决方法
>
> - 1 客户端 - 设置超时时间
>
>
```java
JedisPoolConfig jedisPoolConfig = initPoolConfig();
jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379);
=========> 修改为:
JedisPoolConfig jedisPoolConfig = initPoolConfig();
jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379, 2*1000); //timeout = 2*1000 = connectionTimeout = soTimeout
```
>
>
> `public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port, final int connectionTimeout, final int soTimeout, final String password, final int database, final String clientName)`
>
>
> - 2 客户端 - 回收连接资源
>
>
```java
Jedis jedis = JedisUtils.getJedis();try { //Todo
} catch (Exception e){
throw new RuntimeException(e.getMessage(), e);
JedisUtils.returnBrokenResource(jedis); //释放连接
} finally {
JedisUtils.returnResource(jedis); //释放连接
}
----
/** * 回收Jedis对象资源 * * @param jedis */public synchronized void returnResource(Jedis jedis) { if (jedis != null) { jedisPool.returnResource(jedis); }}
/** * Jedis对象出异常的时候,回收Jedis对象资源 * * @param jedis */public synchronized void returnBrokenResource(Jedis jedis) { if (jedis != null) { jedisPool.returnBrokenResource(jedis); }
}
```
>
>
> 在 `Jedis 2.6.2` 以后,由于重写了`jedis.close()`,实现**自动关闭**,`2.6.3`以后正式使用,详见[Deprecates JedisPool returnResource and returnBrokenResource](https://github.com/xetorthio/jedis/pull/912) ,这样可以代码使用JDK7中新增的`try-with-resource`语法糖,这样代码会简洁很多如下:
>
```java
try (Jedis jedis = JedisUtils.getJedis()) {
//Todo
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
```
>
> - 3 通过ip排查对应的service服务,查看是否还可以进行优化。
> - 4 查看空闲超时时间: `config get timeout`
>
>
>
>
> >
> >
> > `0` : 默认不开启
> >
>
>
>
> - 5 设置空闲超时时间 : `config set timeout {second}`
>
>
>
>
> >
> >
> > 建议为`0`,尤其是有用分布式锁的情况下、具体看业务场景
> >
> > 如:配置默认空闲超时时间为60s : `config set timeout 60`
> >
>
>
>
> - 6 `config rewrit` : 保存
>
>
>
>
> >
> >
> > 可在 `redis.conf` 配置文件中添加重启生效。
> >
>
>
# X 参考文献
- [redis 连接工具_redis之timeout(默认建议为0) , maxclients(重要) - 博客园](https://www.cnblogs.com/cheyunhua/p/15903942.html)
- [解决Redis 连接池报错:ERR max number of clients reached - CSDN](https://blog.csdn.net/tengxing007/article/details/88354218) 【推荐】
- [生产-已解决-Redis连接数占满 报错 (error) ERR max number of clients reached - CSDN](https://blog.csdn.net/zhanshixiang/article/details/129693694) 【推荐】
>
>
> ` (error) ERR max number of clients reached`
>
> "我仔细审查了一下前同事写的Redis工具类,发现连接用完,全都没有归还连接"
>
```java
public T get(String key, String modulePrefix, Class t) {
checkJedisPool();
key = generateKey(key, modulePrefix);
try (Jedis jedis = jedisPool.getResource()) {
String valueStr = jedis.get(key);
return parse(valueStr, t);
}
}
```
本文来自投稿,不代表本站立场,如若转载,请注明出处:http//www.knowhub.vip/share/2/3651
- 热门的技术博文分享
- 1 . ESP实现Web服务器
- 2 . 从零到一:打造高效的金仓社区 API 集成到 MCP 服务方案
- 3 . 使用C#构建一个同时问多个LLM并总结的小工具
- 4 . .NET 原生驾驭 AI 新基建实战系列Milvus ── 大规模 AI 应用的向量数据库首选
- 5 . 在Avalonia/C#中使用依赖注入过程记录
- 6 . [设计模式/Java] 设计模式之工厂方法模式
- 7 . 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
- 8 . SQL 中的各种连接 JOIN 的区别总结!
- 9 . JavaScript 中防抖和节流的多种实现方式及应用场景
- 10 . SaltStack 远程命令执行中文乱码问题
- 11 . 推荐10个 DeepSeek 神级提示词,建议搜藏起来使用
- 12 . C#基础:枚举、数组、类型、函数等解析
- 13 . VMware平台的Ubuntu部署完全分布式Hadoop环境
- 14 . C# 多项目打包时如何将项目引用转为包依赖
- 15 . Chrome 135 版本开发者工具(DevTools)更新内容
- 16 . 从零创建npm依赖,只需执行一条命令
- 17 . 关于 Newtonsoft.Json 和 System.Text.Json 混用导致的的序列化不识别的问题
- 18 . 大模型微调实战之训练数据集准备的艺术与科学
- 19 . Windows快速安装MongoDB之Mongo实战
- 20 . 探索 C# 14 新功能:实用特性为编程带来便利