Multithreading jedis

5,848 views
Skip to first unread message

Sebastián Galkin

unread,
Sep 30, 2010, 6:34:50 PM9/30/10
to Jedis
Hi, I'm using jedis in a heavily multithreaded application. I noticed
that after a while jedis gets confused, and all following requests
result in an error parsing redis response. I'm using the same Jedis
instance from all threads. Should I have a Jedis object for each
thread (doing it this way I don't see any errors)? Are Jedis instances
supposed to be thread safe?

Thank you

Jonathan Leibiusky

unread,
Sep 30, 2010, 6:49:28 PM9/30/10
to jedis...@googlegroups.com
Hi!
Yes came to the right conclusion. Jedis is not thread safe (should add that to the documentation).
You can either use one Jedis per thread or JedisPool, which is a thread safe pool of jedis.

I would recommend JedisPool for most cases since it will reuse Jedis instances, resulting in better performance.

It is easy to use, just create it and store it somewhere accesible for all threads. For example:

class JedisFactory {
    public JedisPool jedisPool;
    static void JedisFactory() {
        jedisPool = new JedisPool("localhost");
        jedisPool.init();
    }
}


and from your thread:

Jedis jedis = JedisFactory.jedisPool.getResource();
...
...
JedisFactory.jedisPool.returnResource(jedis);

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.

Oh, and one last thing... call jedisPool.destroy() when finishing your app.

Jonathan



2010/9/30 Sebastián Galkin <para...@gmail.com>

Sebastián Galkin

unread,
Sep 30, 2010, 7:27:50 PM9/30/10
to Jedis
Great, thank you!!

On Sep 30, 7:49 pm, Jonathan Leibiusky <ionat...@gmail.com> wrote:
> Hi!
> Yes came to the right conclusion. Jedis is not thread safe (should add that
> to the documentation).
> You can either use one Jedis per thread or JedisPool, which is a thread safe
> pool of jedis.
>
> I would recommend JedisPool for most cases since it will reuse Jedis
> instances, resulting in better performance.
>
> It is easy to use, just create it and store it somewhere accesible for all
> threads. For example:
>
> class JedisFactory {
>     public JedisPool jedisPool;
>     static void JedisFactory() {
>         jedisPool = new JedisPool("localhost");
>         jedisPool.init();
>     }
>
> }
>
> and from your thread:
>
> Jedis jedis = JedisFactory.jedisPool.getResource();
> ...
> ...
> JedisFactory.jedisPool.returnResource(jedis);
>
> 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.
>
> Oh, and one last thing... call jedisPool.destroy() when finishing your app.
>
> Jonathan
>
> 2010/9/30 Sebastián Galkin <paras...@gmail.com>

Ted Pennings

unread,
Oct 1, 2010, 4:41:53 PM10/1/10
to Jedis
Do you have any advice on how to implement this in a servlet app? I'm
using Spring MVC so I have the full splendor of Spring available.

Right now I'm thinking that I would need to write an object pool that
returns Jedis proxy objects so I could catch the broken pipe
exceptions when redis sockets timeout =(

Thanks

Jonathan Leibiusky

unread,
Oct 1, 2010, 5:46:28 PM10/1/10
to jedis...@googlegroups.com
You don't need to do that if you use JedisPool.
You just need to create a bean and tell spring that JedisPool is Singleton.
It's been a while since the last time I used Spring. But it think it should be something like this:

<bean id="jedisPool" class="redis.clients.JedisPool" scope="singleton" init-method="init">
<constructor-arg type="String"><value>localhost</value></constructor-arg>
</bean>

This will tell spring to create a bean called "jedisPool" with default params and will initialize it.
Then you can tell spring to inject this bean pretty much everywhere.
Having JedisPool you can ask for a Jedis and do all your job.
Just remember to return it back once you finished using it.

Jonathan

Deepak Pol

unread,
Mar 14, 2015, 5:06:17 PM3/14/15
to jedis...@googlegroups.com
Hi,

I am facing this issue in my application which is heavily multi-threaded too, and I'm getting intermittent ClassCastExceptions. Searched on the internet quite a bit, and most of the solutions seem to point to using a pool. However, even after using a pool I'm still getting this exception quite often. FYI, I am not using pipelining.

I am using spring redis support (RedisTemplate) to configure pool - 

<bean id="jedisConnFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
redis:usePool="true" redis:poolConfig-ref="jedisPoolConfig" redis:hostName="${redis.datasource.hostName}"
redis:database="${redis.database.index}" redis:port="${redis.datastore.port}"/>

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.conn.maxIdle}"/>
<property name="maxTotal" value="${redis.conn.maxTotal}"/>
<property name="minIdle" value="${redis.conn.minIdle}"/>
<property name="testOnBorrow" value="true"/>
</bean>

Any help to identify what could be the issue will help.

Thanks in advance.
Reply all
Reply to author
Forward
0 new messages