Jedis和Lettuce的异步能力

35

我正在使用Redis和Akka,所以我需要非阻塞调用。Lettuce已经内置了异步-未来调用。但是 Redis 推荐的客户端是 Jedis。有人能告诉我是否正确地使用了它们?如果是这样的话,哪一个更好。

JEDIS 我正在使用静态 Jedis 连接池获取连接,并使用 Akka future 回调来处理结果。我的担忧在于,当我使用另一个线程(Callable)来获取结果时,该线程最终会阻塞等待结果。而 Lettuce 可能有更有效的方法来处理这个问题。

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

生菜

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

如果生产环境中莴苣是更好的异步调用选项,那么我应该选择哪种执行器。如果可能的话,我能使用Akka分发器作为Letture future调用的执行上下文吗。

2个回答

63

由于情况不同,因此无法给出唯一的答案。

Jedis和lettuce都是成熟的客户端。要列出Java客户端列表,还有Redisson,它添加了另一层抽象(集合/队列/锁等接口而不是原始的Redis命令)。

这基本上取决于您如何使用客户端。通常情况下,Jedis(用于连接redis的java客户端)在数据访问方面是单线程的,因此通过并发获得的唯一好处是将协议和I/O工作分配给不同的线程。由于lettuce和Redisson在底层使用netty(netty将一个套接字通道绑定到特定的事件循环线程),因此这并不完全适用于它们。

对于Jedis,您只能使用一个连接,每次仅限一个线程。这与Akka actor模型相吻合,因为一个actor实例每次仅被一个线程占用。

另一方面,您需要尽可能多的Jedis连接与处理特定actor的线程数相匹配。如果您开始在不同的actor之间共享Jedis连接,则需要使用连接池或为每个actor实例提供专用的Jedis连接。请记住,您需要自己处理重新连接(一旦Redis连接断开)。

使用lettuce和Redisson,您可以在所有actor之间共享一个连接,因为它们是线程安全的。您不能在以下两种情况下共享一个lettuce连接:

  1. 阻塞操作(因为您将阻塞连接的所有其他用户)
  2. 事务(MULTI/EXEC),因为您将在事务中混合不同的操作,这肯定不是您想要做的事情

Jedis没有异步接口,因此您需要自己完成此操作。这是可行的,并且我使用了类似于MongoDB的东西,将I/O部分卸载/解耦到其他actor中。您可以使用自己的代码方法,但您不需要提供自己的执行程序服务,因为在runnable listener中进行非阻塞操作。

使用Lettuce 4.0,您将获得Java 8支持(由于CompletionStage接口的异步API优势更大),您甚至可以使用RxJava(反应式编程)来处理并发。

Lettuce在并发模型上没有固定意见。它允许您根据需要进行使用,但不建议使用Java 6/7和Guava的普通Future/ListenableFuture API。

希望对您有所帮助,Mark


6

尝试使用Redisson框架。它通过与Project Reactor和RxJava3库的集成,提供了异步API和响应式流API。

异步API使用示例:

RedissonClient client = Redisson.create(config);
RMap<String, String> map = client.getMap("myMap");

// implements CompletionStage interface
RFuture<String> future = map.get("myKey");

future.whenComplete((res, exception) -> {
  // ...
});

使用Project Reactor库的反应式流API示例:

使用Project Reactor库的反应式流API示例:

RedissonReactiveClient client = Redisson.createReactive(config);
RMapReactive<String, String> map = client.getMap("myMap");

Mono<String> resp = map.get("myKey");

RxJava2库使用的反应式流API示例:

RedissonRxClient client = Redisson.createRx(config);
RMapRx<String, String> map = client.getMap("myMap");

Flowable<String> resp = map.get("myKey");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接