Background
Our application uses Jedis-2.2.1
and connects to Redis-2.6
, here's how I get jedis resource :
protected static JedisWrapper getRedisUserWrite(String UDID) { if (redisUserWritePools.get(0) == null) init(); int hash = hash(UDID); Jedis jedis = redisUserWritePools.get(hash).getResource(); jedis.select(dbs.get("redisUserWritePools"+ hash)); return new JedisWrapper(jedis, redisUserWritePools.get(hash)); }
And this is my JedisWrapper
(Unify the management of resources):
public class JedisWrapper { private Jedis jedis; private JedisPool pool; public JedisWrapper(Jedis jedis, JedisPool pool) { this.jedis = jedis; this.pool = pool; } public Jedis get(){ return this.jedis; } public void returnResource() { if(null != this.jedis){ this.pool.returnResource(this.jedis); } } public void returnBrokenResource() { if(null != this.jedis) { this.pool.returnBrokenResource(this.jedis); } this.jedis = null; }}
JedisWrapper
is the container if Jedis instance, here's how I use it :
private static void cacheSDKIDs(String UDID, String[] SDKIDs) { JedisWrapper wrapper = getRedisUserWrite(UDID); try { if (SDKIDs != null) { wrapper.get().del(UDID); wrapper.get().sadd(UDID, SDKIDs); } } catch (JedisConnectionException e) { e.printStackTrace(); wrapper.returnBrokenResource(); }catch (Exception e) { e.printStackTrace(); } finally { wrapper.returnResource(); } }
Note that, SKDIDs
maybe very large(e.g. could reach the maximum of 8KB).
Here's the problem
Every time I restart our application, all redis connections are normal, but several hours later, the Could not get a resource from the pool
Exception comes out. And frequency become higher and higher, then all the connections to Redis are disconnected and can create new connection.
Here's my configuration :
<bean id = "redisConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxActive" value="400" /><property name="maxIdle" value="100" /><property name="minIdle" value="20" /><property name="maxWait" value="4000" /><property name="testOnBorrow" value="true"/><property name="testOnReturn" value="true" /></bean>
Exception Stacktrace:
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at redis.clients.util.Pool.getResource(Pool.java:40) at com.xxxice.redis.BaseRedis.getRedisUserWrite(BaseRedis.java:158) at com.xxx.service.redis.DeviceRedis.cacheSDKIds(DeviceRedis.java:128) at com.xxx.redis.DeviceRedis.cacheDevice(DeviceRedis.java:65) at com.xxx.service.DeviceService.update(DeviceService.java:88) at com.xxx.controller.Devices.update(Devices.java:25) ... 32 moreCaused by: java.util.NoSuchElementException: Timeout waiting for idle object at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1174) at redis.clients.util.Pool.getResource(Pool.java:38) ... 37 more