《Redis常见客户端异常汇总(Jedis篇).docx》由会员分享,可在线阅读,更多相关《Redis常见客户端异常汇总(Jedis篇).docx(7页珍藏版)》请在第壹文秘上搜索。
1、JediS是RediS的java版本的客户端实现。在RediS客户端的使用过程中,无论是客户端使用不当或者RediS服务端出现问题,客户端会反应出一些异常,本文分析了Jedis使用过程中常见的异常情况。一、无法从连接池获取到连接JediSPooI中的JediS对象个数是有限的,默认是8个。这里假设使用的默认配置,如果有8个JediS对象被占用,并且没有归还,如果调用者还要从JediSPoOl中借用Jedis,就需要进行等待(例如设置了maxWaitMillisO),如果在maxWaitMillis时间内仍然无法获取到Jedis对象就会抛出如下异常。redis.clients.jedis.exc
2、eptions.JedisconnectionExceptionzcouldnotgetaresourcefromthepool.Causedbyijava.Uti1.NosuchElementExceptionzTmons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)还有一种情况,就是设置了blockWhenExhausted=false,那么调用者发现池子中没有资源时,会立即抛出异常不进行等待下面的异常就是blockWhenExhausted=false时的效果。redis.clients.jed
3、is.exceptions.JedisconnectionExceptionzcouldnotgetaresourcefromthepool.Causedby:java.util.NoSuchElementException:Pmons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)对于这个问题,需要重点讨论的是为什么连接池没有资源了,造成没有资源的可能的原因非常多1 .客户端:高并发下连接池设置过小,出现供不应求,所以会出现上面的错误,但是正常情况下只要比默认的最大连接数(8个)多一些即可,因为正常情
4、况下JediSPOoI以及Jedis的处理效率足够高。2 .客户端:没有正确使用连接池,比如没有进行释放,例如下面代码所示:定义JediSPOol,使用默认的连接池配置。GenericObjectPoolConfigpoolConfig=newGenericObjectPoolConfig();JedisPooljedisPool=newJedisPool(poolConfig,l27.0.0.,6379)jJedisPool借用8次连接,但是没有执行归还操作。for(inti=0;i,maxmemory.八、客,端连接数过大如果客户端连接数超过了maxclients,新申请的连接就会出现如下
5、异常:redis.clients.jedis.exceptions.JedisDataException:ERRmaxnumberofclientsreached此时新的客户端连接执行任何命令,返回结果都是如下:127.0.0.k6379gethello(error)ERRmaxnumberofclientsreached这个问题可能会比较棘手,因为此时无法执行RediS命令,一般来说可以从两个方面进行着手。1 .客户端:如果maxclients参数不是很小的话,应用方的客户端连接数基本不会超过maxclients,通常来看是由于应用方对于Redis客户端使用不当造成的。此时如果应用方是分布式
6、结构的话,可以通过下线部分应用节点(例如占用连接较多的节点),使得Redis的连接数先降下来。从而让绝大部分节点可以正常运行,此时在再通过查找程序bug或者调整maxclients进行问题的修复。2 .服务端:如果此时客户端无法处理,而当前Redis为高可用模式(例如RedisSentinel和RedisCluster),可以考虑将当前Redis做故障转移。此问题不存在确定的解决方式,但是无论从哪个方面进行处理,故障的快速恢复极为重要,当然更为重要的是找到问题的所在,否则一段时间后客户端连接数依然会超过maxclientso附GenericobjectPoolConfig的重要属性序号参数名含
7、义默认值1maxActive连接池中最大连接数82maxldle连接池中最大空闲的连接数83minldle连接池中最少空闲的连接数04maxWaitMillis当连接池资源用尽后,调用者的最大等待时间(单位为毫秒),一般不建议使用默认值-1:表示永远不超时,一直等。5JmxEnabled是否开启jmx监控,如果应用开启了jmx端口并且JmxEnabled设置为true,就可以通过jconsole或者jvisualvm看到关于连接池的相关统计,有助于了解连接池的使用情况,并且可以针对其做监控统计true6minEvictableIdleTimcMillis连接的最小空闲时间,达到此值后空闲连接将
8、被移除30分钟7numTestsPerEvictionRun做空闲连接检测时,每次的采样数38IestOnBorrow向连接池借用连接时是否做连接有效性检测(Ping),无效连接会被移除,每次借用多执行一次ping命令false序号参数名含义默认值9IestOnRetum向连接池归还连接时是否做连接有效性检测(Ping),无效连接会被移除,每次归还多执行一次ping命令false10IestWhileIdIe向连接池借用连接时是否做连接空闲检测,空闲超时的连接会被移除false11timeBetweenEvictionRunsMillis空闲连接的检测周期(单位为毫秒)-1:表示不做检测12b
9、lockWhenExhausted当连接池用尽后,调用者是否要等待,这个参数是和maxWaitMillis对应的,只有当此参数为true时,InaxWaitMillis才会生效Redis客户端处理介绍了有关RediS如何从网络层的角度处理客户端的信息:连接,超时,缓冲区以及其他类似主题。本文包含的信息仅适用于Redis版本2.6或更高版本。如何接受客户端的连接?Redis通过监听一个TCP端口或者Unixsocket的方式来接收客户端的连接,当一个新的客户端连接建立后,RedisServer会执行以下一些操作:客户端socket会被设置为非阻塞模式,因为Redis在网络事件处理上采用的是非阻塞多路复用模型。设置TCP_N0DE1.AY属性,禁用Nagle算法,确保在我们的连接不要延迟创建一个可读的文件事件,以便于SOCket传送新数据时立即收集客户端查询初始化客户端连接后,Redis核实可能同时处理的连接数是否已达到上限,这个上限是在RediS.conf配置文件中通过maxclients命令来设置的。万一因为已达到最大连接数的上限而不能