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设置的太少了,或者就是软硬件存在限制。
JedisPoolConfig jedisPoolConfig = initPoolConfig();
jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379);
================================================>
JedisPoolConfig jedisPoolConfig = initPoolConfig();
jedisPool = new JedisPool(jedisPoolConfig, "*.*.*.*", 6379,2*1000);
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,这样可以代码使用JDK7中新增的try-with-resource语法糖,这样代码会简洁很多如下:
try (Jedis jedis = JedisUtils.getJedis()) {
//Todo
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
后续贴一个JedisUtils工具类
建议先断开部分客户端,不然由于报错:max number of clients reached,无法创建连接。
info clients
查看客户端连接数,然后使用client list
查看当前连接的客户端。config set timeout 600
CLIENT KILL
命令来杀掉客户端连接。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
图中Max open file这行参数可以看得到进程能够打开的最大文件描述符为4096(ll /proc/{PID}/fd | wc -l
可以查看已经产生的个数)并非10000,受到了软硬件限制,这可能产生报错的最根本原因。
为了设置maxclients这个参数,官网给与了解决方案,使用ulimit为系统范围的设置,详见Maximum number of clients
这个方式的前置条件是 hard limit is big enough ,会看上面的截图,Max open file的硬件限制也是4096,达到了最大值,于是有了如下的解决方案
# 具体设置多少根据实际情况而定
* soft nofile 65536 # open files (-n)
* hard nofile 65536
* soft nproc 65565
* hard nproc 65565 # max user processes (-u)