Redisson和Jedis在redis方面的比较

48
现在我需要使用一个Java客户端来访问Redis。我遇到了JedisRedisson编辑:由于问题有点基于个人观点,因此重新构思。
哪个在速度方面更有效率?有任何基准测试吗?
它们中的哪一个能够提供以下功能?
- 分布式锁(并更新映射中的一些键) - 自动密钥过期通知,但我希望只有一组订阅者中的特定订阅者接收此通知(类似于Apache Kafka中的消费者组概念)。如何实现这一点?
PS:请不要将其标记为this的重复内容。

2
从我的角度来看,Reddison对于您的任务更好,因为它至少涵盖了列表中的一个点[https://github.com/redisson/redisson/wiki/8.-distributed-locks-and-synchronizers]。而使用Jedis,则需要自己实现,因为Jedis只是Redis的有用Java API。 - Vlad Bochenin
1个回答

82

这个问题是基于个人观点的,但让我们了解一些客观的观点:

简短版:

选择驱动程序取决于多种因素:

  • 额外依赖
  • 编程模型
  • 可扩展性
  • 对高级特性实现的看法
  • 您的项目前景以及您想要发展的方向

说明

额外依赖

一些项目对添加库时的附加依赖和暂时依赖有自己的看法。

Jedis 几乎没有依赖关系,它需要 Apache Commons Pool 2 来进行连接池化。

Redisson 需要 Netty、JCache API 和 Project Reactor 作为基本依赖。它是可扩展的,因为它与许多其他库(如 Tomcat Session 存储)集成。

编程模型

这是您与 Redis 客户端交互的方式。它还定义了抽象级别。

Jedis 是一个低级驱动程序,将 Redis API 公开为 Java 方法调用:

Jedis jedis = …;

jedis.set("key", "value");

List<String> values = jedis.mget("key", "key2", "key3");

Redisson是一个高级客户端,通过各种API对象来公开其功能:

Redisson redisson = …

RMap map = redisson.getMap("my-map"); // implement java.util.Map

map.put("key", "value");

map.containsKey("key");

map.get("key");

每个调用都会触发一个或多个 Redis 调用,其中一些使用 Lua 实现(Redis“脚本”)。

可扩展性

Java 有多个可用的驱动程序,具有各种属性可能适合您的项目。 可扩展性也会涉及其中。 看驱动程序,它归结于驱动程序如何使用其资源以及它们支持哪些编程模型。

Jedis 使用阻塞 I/O,方法调用是同步的。 程序流程需要等待,直到 socket 处理完 I/O。 没有异步(FutureCompletableFuture)或反应式支持(RxJava Observable 或 Reactive Streams Publisher)。

Jedis 客户端实例不是线程安全的,因此需要连接池(每个调用线程一个 Jedis 实例)。

Redisson 使用非阻塞 I/O 和基于 Netty 的事件驱动通信层。 方法调用是同步的、异步的或反应式的(通过 Project Reactor 2.0 或 3.1)。 连接已汇集,但 API 本身是线程安全的,并且需要较少的资源。 我不是很确定,但您甚至可以在单个连接上操作。 这是与 Redis 一起工作的最有效方式。

客户端实现的观点

这些段落涉及客户端是如何实现的。

两个客户端都具有出色的功能覆盖,您可以使用两个库来满足您的要求。

Jedis 是一个简单的实现,只是将命令写入 OutputStream 并解析响应。 没有更多了。

如果您需要高级功能,则需要使用 Redis API 来实现这些功能。 它使您完全控制您调用的命令和结果行为。 在此处实现自己的功能可能需要额外的努力。

Redisson 是一个高级客户端,通过其抽象提供功能。 虽然可以使用这些对象而不需要知道它们由 Redis 支持(MapListSet等),但每个 API 调用都会转换为一个或多个 Redis 调用,其中一些是 Lua 脚本执行。

您可能喜欢或不喜欢 Redisson 的行为方式以及如何实现功能,但最终,您无法做太多关于它。 使用 Redisson 的高级功能可能会减少您的实现工作。

前景

该部分完全取决于您的目标。 Jedis 支持所有 Redis API 命令、Redis 独立版、Redis Sentinel 和 Redis Cluster。 在主-从设置中没有从属读取,但我认为这只是时间问题,直到 jedis 提供这些功能。

使用 jedis,您无法进行异步操作,并且使用 AWS ElastiCache 的高级功能或从属读取需要您自己实现。

Redisson 具有各种设置的广泛覆盖范围。 它支持 Jedis 支持的所有内容,并为主/从设置提供读取策略,在 AWS ElastiCache 方面提供了改进的支持。


10
谢谢你提供这么详细的解释!我不是完全确定,但也许你甚至可以只使用单个连接进行操作。确信无疑,Redisson 可以使用单个连接工作 :) - Nikita Koksharov
1
@NikitaKoksharov 当你说redisson是异步的时候,它是通过将消息排队到一个线程执行器或队列上来实现的,对吗?这是一个带有待发送和接收消息队列的连接池。那么redisson在这里有什么不同呢?此外,Jedis是同步的,但是你可以在基于队列的系统中包装它成为一个future。那么redisson真的可以管理来自多个线程的单个客户端之间的通信吗? - mjs
1
或者每个连接有一个线程(执行器),从各个线程处理传入的排队命令,在一个时间内处理一条命令。使用这种模式可以允许多个线程进行通信,但在其核心只发送一个命令,接收响应,然后可以发送下一个命令。对吗? - mjs
1
我认为人们对此有着很大的看法差异。如果Redisson确实能够通过一个连接使用多线程进行通信,那么它与无法做到这一点的Jedis根本不同,但我不确定它是否可以。您能否澄清一下?它是否可以在仅使用一个Redis连接的情况下从各个线程同时发送和接收多个命令? - mjs
1
@mmm 所有发送的 Redis 请求/响应都由 nettyThreadGroup 处理,该组具有多个线程,并可通过 nettyThreads 设置进行更改。 - Nikita Koksharov

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