Hi,
Summary
I'm having a problem that a program runs out of connections to Redis, and guessing that it might be caused by scalacache-redis.
I'm not 100% sure, but I think one of the three options below needs to be taken:
- Use
jedisPool.returnResource(jedis)
instead of jedis.close()
- Make
RedisCache#jedisPool
public, so client code can call JedisPool#destroy
- Instantiate plain
Jedis
every time instead of getting one from the pool
Details
jedis.close is a problem?
Here is a sample code from the Jedis wiki:
Jedis jedis = null;
try {
jedis = pool.getResource();
/// ... do stuff here ... for example
jedis.set("foo", "bar");
String foobar = jedis.get("foo");
jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike");
Set<String> sose = jedis.zrange("sose", 0, -1);
} finally {
if (jedis != null) {
jedis.close();
}
}
/// ... when closing your application:
pool.destroy();
I also took a brief look at Jedis source code, and it seems Jedis#close
actually closes the connection. The sample code above calls pool.destroy()
at the end, so it doesn't matter, but I don't think client code should close a connection taken from the connection pool (in general, no?)
This is an old thread, so I'm not sure this is still valid now,
https://groups.google.com/forum/?fromgroups=#!topic/jedis_redis/UeOhezUd1tQ
but it says:
Returning the resource to the Pool is important, so remember to do it. Otherwise when closing your app it'll wait for the resource to return.
The sample code and wiki page recommend two different ways, and they are kinda contradicting, but in any case, I guess calling only Jedis#close
isn't enough.
Also, another Jedis wiki page says the following:
Forgetting pool.destroy keeps the connection open until timeout is reached.
My conclusion
Now that we've got two options.
Returning the resource to the Pool is important, so remember to do it. Otherwise when closing your app it'll wait for the resource to return.
If the above sentence is still valid, the option below is the way to go:
Use jedisPool.returnResource(jedis)
instead of jedis.close()
If we want to follow the sample doc, we want to call JedisPool#destroy
, so the following is an option:
Make RedisCache#jedisPool
public, so client code can call JedisPool#destroy
We also have an option of not using connection pooling, and sticking to plain Jedis
, in which case, Jedis#close
should be a valid way when you finish using the connection.
Thanks.
EDIT:
Forgot to mention that sedis uses returnResourceObject
, which is a bit different from returnResource
.