Mar 19th, 2013, 03:36 PM
Redis Connection Management. Using too many connections in one use case
I have noticed that there is a large number of connections opened and closed for a single call to our use case.
Typically in JdbcTemplate with TransactionManager, or contextual sessions in Hibernate, the Connection resource is reused so that you weren't abusing the scarce resources.
In our case, since we are also using a third party library that is hooking into our Redis calls that calls a lot. I find almost 50-100 lines of opening and closing the connections. If the RedisTemplate would cache the connection in ThreadLocal or something (which I see in ConnectionUtils) then this wouldn't be a problem.
Are there any solutions, properties, of on ConnectionFactories that can be set to fix this?
Mar 20th, 2013, 11:30 AM
I've actually been looking into this a bit recently. At the moment, the only way to bind a connection to the current thread is by wrapping your calls in a SessionCallback. We are starting to think about other ways to do this, possibly for the next 1.1 M1 release (suggestions welcome), certainly we could bind through use of @Transactional, but not sure if it makes sense to use this in a pure Redis case, as Redis doesn't support JTA/XA-like transactions. Nonetheless, we need some type of scoping.
That being said, if you are using Jedis, Jredis, or RJC, you should be making use of a connection pool by default, so calls to "close" on our connection objects are just returning the underlying connection to the pool and not closing the socket. Right now we are potentially opening/closing a large number of connections with Lettuce and SRP, which don't have pool impls. I'm working on a solution for this with Lettuce at the moment (possibly sharing the underlying connection in non-blocking, non-tx cases).
Mar 20th, 2013, 02:15 PM
Thanks Jen. Good to hear from you. Hope everything is going well.
I can change the code to use SessionCallback.
We actually have a two fold problem with our code. Basically we are using Redis as a cache for Web Sessions in Apache Shiro security. So not only do we have the issue with getting open and closed. Shiro calls the cache about 200 times in a single Http Request. I managed to reduce it in a minor way with storing the Session in ThreadLocal. But Shiro also does those calls multi-threaded, so one thread might have the Session stored in ThreadLocal but the other Threads don't have access to it.
Mar 21st, 2013, 01:46 PM
So on the Shiro end I was able to fix the problem so that it won't call the code that would need to connect to Redis. And in the couple of methods that still needed to use RedisTemplate a bit, to use a RedisCallback implementation.
But, I did notice something else, not specific to this thread, but a request anyway.
So that you can then start adding key/value pairs to the hash does not have a overloaded version that can be used to set the timeout or time to live for that key. Or even in the Operations classes like HashOperations.
I thought I saw in just one class, one method to add a key to Redis that allowed you to set the timeout at the same time.
So this would require developers to have to call two methods to put a key in with a time to live, which in this case would cause two Connections to be used.