问题




redis连接数高 redis连接池最大连接数_django


[ERROR 2023-01-06 15:37:58,877] jwtCalibrateHandler 48 max number of clients reached

早上突然看到反馈说redis连接异常,就是这个:max number of clients reached。问题很显然就是redis连接数超了.

原因分析

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、设置超时时间(客户端找各自框架设置即可)

JedisPoolConfig jedisPoolConfig = initPoolConfig();

jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379);

================================================>

JedisPoolConfig jedisPoolConfig = initPoolConfig();

jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379,2*1000);

服务端

断开空闲连接

建议先断开部分客户端,不然由于报错:max number of clients reached,无法创建连接。

  1. 使用redis-cli进入命令行,使用info clients 查看客户端连接数,然后使用client list查看当前连接的客户端。


redis连接数高 redis连接池最大连接数_客户端_02


  1. 设置参数timeout(客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能)自动断开连接,键入config set timeout 600


redis连接数高 redis连接池最大连接数_django_03


可以看到连接数由3430变为709减低了不少,当然也可以选择使用CLIENT KILL命令来杀掉客户端连接。

-------------------------到此这个问题基本可以解决,下面部分选读-----------------------------------------

设置maxclients

配置文件redis.conf

maxclients 10000

启动参数

$ ./redis-server --maxclients 10000

命令

CONFIG set maxclients 10000

系统平台

由于创建连接数需要分配和消耗系统资源,所以在设置maxclients的时候系统是有预设限制的,如上,10000个连接数是现在redis版本的默认值,由于系统软硬件限制,redis-server启动时候是无法分配到资源的

$ ./redis-server --maxclients 10000
[41422] 23 Jan 11:28:33.179 # Unable to set the max number of files limit to 10032 (Invalid argument), setting the max clients configuration to 4096.
# 获取redis PID
$ ps -ef | grep redis-server
# 获取redis的能够打开的最大文件描述符
cat /proc/{PID}/limints


redis连接数高 redis连接池最大连接数_redis连接数高_04


图中Max open file这行参数可以看得到进程能够打开的最大文件描述符为4096(ll /proc/{PID}/fd | wc -l可以查看已经产生的个数)并非10000,受到了软硬件限制,这可能产生报错的最根本原因。

为了设置maxclients这个参数,官网给与了解决方案,使用ulimit为系统范围的设置,详见Maximum number of clients


redis连接数高 redis连接池最大连接数_客户端_05


这个方式的前置条件是 hard limit is big enough ,会看上面的截图,Max open file的硬件限制也是4096,达到了最大值,于是有了如下的解决方案

1、编辑/etc/security/limits.conf

# 具体设置多少根据实际情况而定
* soft nofile 65536      # open files  (-n)
* hard nofile 65536
 
* soft nproc 65565
* hard nproc 65565       # max user processes   (-u)

2、保存重新登录服务器即可


redis连接数高 redis连接池最大连接数_redis_06


参考文章

JedisPool returnResource and returnBrokenResource https://github.com/xetorthio/jedis/pull/912

redis报错“max number of clients reached" https://blog.51cto.com/11819159/1916133

Redis Clients Handling https://redis.io/topics/clients#maximum-number-of-clients