Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jedis and Lettuce async abilities

I am using redis with Akka so I need no blocking calls. Lettuce has async-future call built into it. But Jedis is the recommended client by Redis. Can someone tell me if I am using both of them the right way. If so which one is better.

JEDIS I am using a static Jedis connection pool to get con and using Akka future callback to process the result. My concern here is when I use another thread (callable) to get the result that thread is eventually going to block for the result. While Lettuce might have some more efficient way of doing this.

 private final class OnSuccessExtension extends OnSuccess<String> {             private final ActorRef senderActorRef;             private final Object message;             @Override             public void onSuccess(String valueRedis) throws Throwable {                 log.info(getContext().dispatcher().toString());                 senderActorRef.tell((String) message, ActorRef.noSender());             }              public OnSuccessExtension(ActorRef senderActorRef,Object message) {                     this.senderActorRef = senderActorRef;                     this.message=message;                 }         }         ActorRef senderActorRef = getSender(); //never close over a future             if (message instanceof String) {         Future<String> f =akka.dispatch.Futures.future(new Callable<String>() {                     public String call() {                         String result;                         try(Jedis jedis=JedisWrapper.redisPool.getResource()) {                             result = jedis.get("name");                         }                         return result;                     }                 }, ex);                 f.onSuccess(new OnSuccessExtension(senderActorRef,message), ex);     } 

LETTUCE

ExecutorService executorService = Executors.newFixedThreadPool(10); public void onReceive(Object message) throws Exception {         ActorRef senderActorRef = getSender(); //never close over a future         if (message instanceof String) {              final RedisFuture<String> future = lettuce.connection.get("name");             future.addListener(new Runnable() {                 final ActorRef sender = senderActorRef;                 final String msg =(String) message;                 @Override                 public void run() {                     try {                         String value = future.get();                         log.info(value);                         sender.tell(message, ActorRef.noSender());                     } catch (Exception e) {                     }                 }             }, executorService); 

If lettuce is a better option for Async calls. Then what type of executor should I go with in production environment. If possible can I use a Akka dispatcher as an execution context for Letture future call.

like image 759
cykopath Avatar asked Sep 30 '15 04:09

cykopath


People also ask

Is Jedis asynchronous?

Jedis has no async interface, so you're required to do this by yourself.

Which is better Jedis or Lettuce?

Unsurprisingly, Jedis is easier to use, but only works with clusters synchronously. Lettuce is harder to use, but enables synchronous, asynchronous and reactive interaction with the cluster.

What is the difference between Redis and Jedis?

Redisson offers in-memory data grid features with support for a variety of distributed objects and services for Redis. Jedis, on the other hand, is a more lightweight offering that lacks certain features of other libraries.

What is Lettuce and Jedis?

Jedis, Lettuce, and clustering Unsurprisingly, Jedis is easier to use but can work with clusters only synchronously. Lettuce is more difficult to use but capable of synchronous, asynchronous, and reactive interaction with the cluster.


1 Answers

There is no one answer to your question because it depends.

Jedis and lettuce are both mature clients. To complete the list of Java clients, there is also Redisson, which adds another layer of abstraction (Collection/Queue/Lock/... interfaces instead of raw Redis commands).

It pretty much depends on how you're working with the clients. In general, Jedis (java based client to connect to redis) is single-threaded in terms of data access, so the only benefit you gain by concurrency is offloading the protocol and I/O work to different threads. That is not fully true to lettuce and Redisson since they use netty under the hood (netty binds one socket channel to a particular event loop thread).

With Jedis, you can use only one connection only with one thread at a time. That correlates nicely with the Akka actor model because one actor instance is occupied only by one thread at a time.

On the other side, you need as much Jedis connections as threads that deal with a particular actor. If you start sharing Jedis connections across different actors, you either go for connection pooling, or you need to have a dedicated Jedis connection per actor instance. Please keep in mind that you need to take care of the reconnection (once a Redis connection is broken) by yourself.

With Redisson and lettuce, you get transparent reconnection if you wish to do so (That's the default value to lettuce, not sure about Redisson).

By using lettuce and Redisson you can share one connection amongst all actors because they are thread-safe. You cannot share one lettuce connection in two cases:

  1. Blocking operations (since you would block all other users of the connection)
  2. Transactions (MULTI/EXEC, since you would mix different operations with the transactions and that is certainly a thing you do not want to do so)

Jedis has no async interface, so you're required to do this by yourself. That's feasible, and I did something similar with MongoDB, offloading/decoupling the I/O part to other actors. You can use the approach from your code, but you're not required to provide an own executor service because you do non-blocking operations in the runnable listener.

With lettuce 4.0 you'll get Java 8 support (which is way better in terms of the async API because of the CompletionStage interface), and you can even use RxJava (reactive programming) to approach concurrency.

Lettuce is not opinionated on your concurrency model. It allows you to use it according to you needs, except the plain Future/ListenableFuture API of Java 6/7 and Guava is not very nice to use.

HTH, Mark

like image 144
mp911de Avatar answered Sep 20 '22 00:09

mp911de