本文介绍了Jedis和生菜异步能力的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用redis与Akka,所以我不需要阻止调用。生菜具有内置的异步未来调用。但是Jedis是Redis的推荐客户。如果我以正确的方式使用它们,有人可以告诉我。如果是这样哪一个更好。

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
我使用静态Jedis连接池来获取con并使用Akka将来的回调处理结果。我关心的是当我使用另一个线程(可调用)来获得线程最终将阻塞结果的结果时。虽然Lettuce可能有一些更有效的方法。

JEDISI 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);

如果生菜是Async调用的更好选择。那么我应该在生产环境中使用什么类型的执行程序。如果可能的话,我可以使用Akka调度程序作为Letture future call的执行上下文。

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.

推荐答案

你的问题没有一个答案因为它取决于。

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

Jedis和生菜都是成熟的客户。要完成Java客户端列表,还有Redisson,它添加了另一层抽象(Collection / Queue / Lock / ...接口而不是原始Redis命令)。

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).

这很大程度上取决于你如何与客户合作。通常,Redis在数据访问方面是单线程的,因此通过并发获得的唯一好处是将协议和I / O工作卸载到不同的线程。这对于莴苣和Redisson来说并不完全正确,因为它们在引擎盖下使用netty(netty将一个套接字通道绑定到特定的事件循环线程)。

It pretty much depends on how you're working with the clients. In general, 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).

使用Jedis,你可以一次仅使用一个线程只使用一个连接。这与Akka actor模型很好地相关,因为一个actor实例一次只被一个线程占用。

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.

另一方面,你需要尽可能多的Jedis连接作为线程与特定演员打交道。如果您开始在不同的actor之间共享Jedis连接,则可以选择连接池,也可以为每个actor实例提供专用的Jedis连接。请记住,您需要自己处理重新连接(一旦Redis连接断开)。

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.

使用Redisson和生菜,如果你有透明的重新连接希望这样做(这是生菜的默认值,不确定Redisson)。

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).

通过使用莴苣和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. 阻止操作(因为你会阻止连接的所有其他用户)

  2. 交易( MULTI / EXEC ,因为您会将不同的操作与交易混合在一起肯定是你不想这样做的事情)

  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没有异步接口,所以你需要这样做你自己。这是可行的,我做了一些与MongoDB类似的东西,将I / O部分卸载/解耦给其他actor。您可以使用代码中的方法,但是您不需要提供自己的执行程序服务,因为您在runnable侦听器中执行非阻塞操作。

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.

使用生菜4.0你将获得Java 8支持(由于CompletionStage接口在异步API方面更好),你甚至可以使用RxJava(反应式编程)来实现并发。

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.

生菜对你的并发模型没有意见。它允许您根据需要使用它,除了Java 6/7的普通 Future / ListenableFuture API和番石榴不是很好用。

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

这篇关于Jedis和生菜异步能力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-07 03:39