当前位置: 首页 > 知识库问答 >
问题:

杰迪斯和莴苣异步能力

缑桐
2023-03-14

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

绝地武士我正在使用一个静态绝地武士连接池来获取con,并使用Akka future回调来处理结果。我在这里关心的是,当我使用另一个线程(可调用)来获得结果时,该线程最终将阻止该结果。而莴苣可能有更有效的方法。

 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调度程序作为未来调用的执行上下文。

共有2个答案

黄博艺
2023-03-14

尝试Redisson框架。它提供了异步API以及通过与Project Reactor和RxJava3 libs集成支持的反应流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) -> {
  // ...
});

Reactive Streams API with Project React lib使用示例:

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

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

带有RxJava2 lib的反应流API使用示例:

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

Flowable<String> resp = map.get("myKey");
胡曾笑
2023-03-14

你的问题没有一个答案,因为这要视情况而定。

绝地武士和莴苣都是成熟的客户。为了完成Java客户机列表,还有Redisson,它添加了另一层抽象(Collection/Queue/Lock/…接口,而不是原始的Redis命令)。

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

使用Jedis,一次只能使用一个线程的连接。这与Akka演员模型非常相关,因为一个演员实例一次只被一个线程占用。

另一方面,你需要的绝地连接和处理特定角色的线程一样多。如果你开始在不同的参与者之间共享绝地连接,你要么选择连接池,要么每个参与者实例都需要一个专用的绝地连接。请记住,您需要自己处理重新连接(一旦Redis连接断开)。

使用Redisson和莴苣,如果愿意,可以获得透明的重新连接(这是莴苣的默认值,不确定Redisson)。

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

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

Jedis没有异步接口,所以你需要自己做这件事。这是可行的,我对MongoDB做了类似的事情,将输入/输出部分卸载/解耦给其他参与者。您可以使用代码中的方法,但不需要提供自己的执行器服务,因为您在可运行侦听器中执行非阻塞操作。

使用莴苣4.0,您将获得Java8支持(由于CompletionStage接口,这在异步API方面要好得多),您甚至可以使用RxJava(反应式编程)来实现并发。

莴苣对您的并发模型并不固执己见。它允许您根据需要使用它,除了Java 6/7和Guava的普通未来/可上市未来API不太好用之外。

嗯,马克

 类似资料:
  • 在配置包中配置Jedis和Redis后。我用bean注释创建了jedisConnectionFactory和redisTemplate。但是应用程序无法运行“错误:创建名为“redisConnectionFactory”的bean。我需要做什么?

  • 我正在开发JDK 1.8,但我不知道为什么“发布”不起作用。Redis“set”命令正在处理数据。 代码段: 从日志调试输出:

  • 主要内容:迪杰斯特拉算法的实现思路,迪杰斯特拉算法的具体实现迪杰斯特拉算法用于查找图中某个顶点到其它所有顶点的最短路径,该算法既适用于无向加权图,也适用于有向加权图。 注意,使用迪杰斯特拉算法查找最短路径时,必须保证图中所有边的权值为非负数,否则查找过程很容易出错。 迪杰斯特拉算法的实现思路 图 1 是一个无向加权图,我们就以此图为例,给大家讲解迪杰斯特拉算法的实现思路。 图 1 无向加权图 假设用迪杰斯特拉算法查找从顶点 0 到其它顶点的最短路径,具体过

  • 我有一个带有一个主服务器和两个从服务器的Elasticache设置。我仍然不确定如何传递主从RedisURI列表以构建用于。我只看到对具有单个主机和端口的标准配置的支持。 我知道在为Redis主/从配置Spring Data Redis时会遇到类似的问题 但我认为它不适用于ElastiCache主/从设置,因为目前上述代码将尝试使用MasterSlaveTopologyProvider来发现从IP

  • 我使用springboot 2.3.9.RELEASE的莴苣客户端连接AWS redis elasticcache主/从。I'am able to write and read but a error is抛出每隔5000ms一次 这项服务对我的pourpose很好,但我想删除错误或知道如何修复它。 我已经读了很多关于它的书,用AWS配置spring数据redis的最好方法是使用RedisticM

  • 我使用的是Spring2.1.1和Redis4.0.1。我已经配置了两台节点计算机,一台具有主配置,另一台具有从配置。我正在两个系统上使用jedis(不使用spring-jedis)运行Springboot应用程序,出现了不同的情况- > 在主节点上运行应用程序(用主节点配置的redis)时,数据会集中在缓存中。 在从节点上运行应用程序时(redis配置了从节点),出现异常-(i.)我能够从sen