早上发现微服务连不上redis cluster了,看来下日志如下

[root@win-jrh378d7scu 7005]# bin/redis-cli -c -h 15.31.213.183 -p 7005
15.31.213.183:7005> cluster info
ERR max number of clients reached
15.31.213.183:7005>

2019-03-26 22:00:30.011 http-nio-9090-exec-4 ERROR org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:182) - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool] with root cause
java.util.NoSuchElementException: Unable to validate object
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:494) ~[commons-pool2-2.4.3.jar!/:2.4.3]
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361) ~[commons-pool2-2.4.3.jar!/:2.4.3]
at redis.clients.util.Pool.getResource(Pool.java:49) ~[jedis-2.9.0.jar!/:?]
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226) ~[jedis-2.9.0.jar!/:?]
at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnectionFromSlot(JedisSlotBasedConnectionHandler.java:66) ~[jedis-2.9.0.jar!/:?]
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:116) ~[jedis-2.9.0.jar!/:?]
at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:31) ~[jedis-2.9.0.jar!/:?]
at redis.clients.jedis.JedisCluster.get(JedisCluster.java:124) ~[jedis-2.9.0.jar!/:?]
at com.hp.nova.utils.RedisClusterUtil.mget(RedisClusterUtil.java:152) ~[classes!/:0.0.1-SNAPSHOT]
at com.hp.nova.service.impl.SectionServiceImpl.getsectionlistBymutipulCode(SectionServiceImpl.java:286) ~[classes!/:0.0.1-SNAPSHOT]
at com.hp.nova.service.impl.SectionServiceImpl$$FastClassBySpringCGLIB$$73b5d4bc.invoke(<generated>) ~[classes!/:0.0.1-SNAPSHOT]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.20.RELEASE.jar!/:4.3.20.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:667) ~[spring-aop-4.3.20.RELEASE.jar!/:4.3.20.RELEASE]
at com.hp.nova.service.impl.SectionServiceImpl$$EnhancerBySpringCGLIB$$c52c4ab.getsectionlistBymutipulCode(<generated>) ~[classes!/:0.0.1-SNAPSHOT]
at com.hp.nova.service.impl.PlanServiceImpl.getChildListDetailByPlan(PlanServiceImpl.java:1051) ~[classes!/:0.0.1-SNAPSHOT]
at com.hp.nova.controller.PlanController.getMultiPlan(PlanController.java:107) ~[classes!/:0.0.1-SNAPSHOT]
at sun.reflect.GeneratedMethodAccessor335.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_131]

首先查看redis.conf中的maxclients大小为默认值,默认为10000。

通过lsof -p 17242 |wc -l  查看redis的连接数,发现连接数量超过10300. 所以出错。

依次重启6个节点的redis进程,再用lsof -p pid |wc -l 命令查看redis进程发现连接数变为60

但是最开始没有重启java微服务的进程,所以java里面还会报错,重启java微服务进程后就好了

2019-03-26 17:13:42.126 http-nio-9090-exec-1 ERROR org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:182) - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is redis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool] with root cause java.util.NoSuchElementException: Pool exhausted
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:452) ~[commons-pool2-2.4.3.jar!/:2.4.3]
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:361) ~[commons-pool2-2.4.3.jar!/:2.4.3]

但是用了半天系统后lsof -p pid |wc -l发现有几个redis进程的连接数又到了5000多,我看了一下我们的yml配置如下,暂时不知道是因为每个微服务 maxTotal: 5000 #最大连接数   的原因导致真的redis连接数不够还是因为java或者.net core的程序问题导致没有释放redis cluster的连接数。先把每个redis的maxclients 设为50000观察几天再说

redis:
nodes: 15.31.213.3:7001,15.31.213.3:7002,15.31.213.239:7003,15.31.213.239:7004,15.31.213.183:7005,15.31.213.183:7006
commandTimeout: 10000 #redis操作的超时时间
maxTotal: 5000 #最大连接数
maxIdle: 30 #最大空闲连接数
minIdle: 5 #最小空闲连接数
maxWait: 3000 #获取连接最大等待时间 ms #default -1
pwd:

晚上又用lsof -p pid |wc -l  查看redis cluster的各个节点的连接数,发现每过几秒就增加5左右的连接数,最近加了定时器会30秒调用自己写的mget方法,所以仔细检查了这个方法

用到了Pipeline  但是没有close jedis的资源,如下

以前有问题代码

// 执行
for (Entry<JedisPool, List<String>> entry : jedisPoolMap.entrySet()) {
try {
currentJedisPool = entry.getKey();
keyList = entry.getValue();
// 获取pipeline
currentPipeline = currentJedisPool.getResource().pipelined();
for (String key : keyList) {
currentPipeline.get(key);
}
// 从pipeline中获取结果
res = currentPipeline.syncAndReturnAll();
currentPipeline.close();
for (int i = 0; i < keyList.size(); i++) {
resMap.put(keyList.get(i), res.get(i) == null ? null : res.get(i).toString());
}
} catch (Exception e) {
logger.error("", e);
return new HashMap<>();
} }

修改后没问题的代码

// 执行
for (Entry<JedisPool, List<String>> entry : jedisPoolMap.entrySet()) {
Jedis jedis=null;
Pipeline currentPipeline = null;
try {
currentJedisPool = entry.getKey();
keyList = entry.getValue();
// 获取pipeline
jedis=currentJedisPool.getResource();
currentPipeline = jedis.pipelined();
for (String key : keyList) {
currentPipeline.get(key);
}
// 从pipeline中获取结果
res = currentPipeline.syncAndReturnAll(); for (int i = 0; i < keyList.size(); i++) {
resMap.put(keyList.get(i), res.get(i) == null ? null : res.get(i).toString());
}
} catch (Exception e) {
logger.error("", e);
return new HashMap<>();
}
finally
{
if(currentPipeline!=null)
{
try {
currentPipeline.close();
} catch (IOException e) {
// TODO Auto-generated catch block
logger.error("",e);
}
}
if(jedis!=null)
{
jedis.close();
}
} }

所以必须要把从JedisPool获取的资源close掉,不然就会连接数一直增长

jedis.close();

重新部署后,发现redis的连接数不会增长了降到了100左右,问题解决

首先查看redis.conf中的maxclients大小为默认值,默认为10000。

通过lsof -p pid |wc -l ,发现连接数量超过10500. 出错。

解决方法1:

1. 增加redis的最大连接数:修改redis.conf文件的maxclient ,修改到50000.

2.  一般redis的连接使用完毕之后会释放,如果要用lsof命令发现链接始终没有减少,则检查代码,看下使用redis的代码部分是否执行类似close()的函数。将资源进行释放。

通过上述两个方法基本能解决这个问题。

redis cluster 的ERR max number of clients reached 问题排查的更多相关文章

  1. 生产redis client 链接报:ERR max number of clients reached 含义: 达到最大客户端数错误

    1.通过netstat 命令查看TCP又11822个连接  (netstat命令是一个监控TCP/IP网络的非常有用的工具) 2.默认redis最大的连接数10000 ,但是此时无法连接redis客户 ...

  2. 【转】redis报错“max number of clients reached"

    查看redis监控的时候看到redis的graph出现不正常的情况,截图如下: 如上面截图所展示的样子,可以看到redis 的客户端连接数很突兀的上升到10K,又突然下降到0.排除了监控本身的原因,很 ...

  3. max number of clients reached Redis测试环境报错

    现象:测试服务是去redis循环取数据,早上发现服务挂了,手动登陆redis 无法输入命令,报错:max number of clients reached Redis

  4. redis cluster 使用中出现的问题

    问题一 redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirectio ...

  5. jedisCluster 报错: redis.clients.jedis.exceptions.JedisClusterException: No way to dispatch this command to Redis Cluster because keys have different slots.

    根本原因:jedisCluster不支持mget/mset等跨槽位的操作. 版本:2.9.0 解决办法,推荐更改redis的驱动修改为: lettuce lettuce 项目地址:https://gi ...

  6. [转]Redis cluster failover

    今天测试了redis cluster  failover 功能,在切换过程中很快,但在failover时有force 与takeover 之分 [RHZYTEST_10:REDIS:6237:M ~] ...

  7. Redis(十)集群:Redis Cluster

    一.数据分布 1.数据分布理论 2.Redis数据分区 Redis Cluser采用虚拟槽分区,所有的键根据哈希函数映射到0~16383整数槽内,计算公式:slot=CRC16(key)&16 ...

  8. 部署Redis Cluster 6.0 集群并开启密码认证 和 Redis-cluster-proxy负载

    部署Redis Cluster集群并开启密码认证 如果只想简单的搭建Redis Cluster,不需要设置密码和公网访问,可以参考官方文档. 节点介绍 Cluster模式推荐最少有6个节点,本次实验搭 ...

  9. Redis Cluster集群搭建与配置

    Redis Cluster是一种服务器sharding分片技术,关于Redis的集群方案应该怎么做,请参考我的另一篇博客http://www.cnblogs.com/xckk/p/6134655.ht ...

随机推荐

  1. Common Lisp

    [Common Lisp] 1.操作符是什么? 2.quote. 3.单引号是quote的缩写. 4.car与cdr方法. 5.古怪的if语句. 6.and语句. 7.判断是真假. null 与 no ...

  2. Python3 sorted() 函数

    Python3 sorted() 函数  Python3 内置函数 描述 sorted() 函数对所有可迭代的对象进行排序操作. sort 与 sorted 区别: sort 是应用在 list 上的 ...

  3. jquery对象的遍历$(selector).each()

    <!DOCTYPE html> <html> <head> <script language="javascript" src=" ...

  4. Java程序设计17——多线程-Part-C

    11 使用管道流 前面介绍的两种方式与其称为线程之间的通信,还不如称为线程之间协调运行的控制策略.如果需要在两条线程之间进行更多的信息交互,则可以考虑使用管道流进行通信. 管道流有3中存在形式:Pip ...

  5. 如何用Python实现常见机器学习算法-1

    最近在GitHub上学习了有关python实现常见机器学习算法 目录 一.线性回归 1.代价函数 2.梯度下降算法 3.均值归一化 4.最终运行结果 5.使用scikit-learn库中的线性模型实现 ...

  6. QQ互联

    [移动应用接入概述] QQ互联开放平台为第三方移动应用提供了丰富的API.第三方移动应用接入QQ互联开放平台后,即可通过调用平台提供的API实现用户使用QQ账号登录移动应用功能,且可以获取到腾讯QQ用 ...

  7. 如何在Windows环境下安装Linux系统虚拟机

    如何在Windows环境下安装Linux系统虚拟机 本篇经验写给想要入门学习C语言的小白们.Windows系统因为使用窗口图形化,操作简单,功能多样,所以我们在Windows环境下可以做到很多,但想要 ...

  8. MFC中的一般经验之谈5

    MFC中提供了CString的类,可以用在一切使用字符串的地方.可以完美取代const char* 或者 LPCTSTR(经常在WinAPI)中传递参数.并且如果需要通过空间进行字符串的数据传递DDX ...

  9. CAS实战のclient自定义过滤器

    我们在配置cas client肯定写过如下代码: <filter> <filter-name>CASFilter</filter-name> <filter- ...

  10. devexpress停靠菜单

    dxDockSite1.Width := 27; dxDockPanel1.DockTo(dxDockSite1, dtLeft, 0); dxDockPanel2.DockTo(dxDockPane ...