Redisson 4.7.0 已发布。这个 Java Redis 客户端不仅封装了字符串、哈希和有序集合等基础命令,还以 Java 对象的方式提供驻内存数据网格能力。新版本把改进重点放在批量 Map 操作和有界队列场景:新增 RMaps、基于数组的 Circular Buffer,并为 RRingBuffer 增加 readNewest()、readOldest() 等读取能力。
这些变化的价值不只是“多了几个 API”。它们让开发者可以直接表达“批量处理多个 Map”“只保留最近 N 条记录”“从缓冲区两端读取数据”等业务意图,减少自行拼接 Redis 命令和维护边界逻辑的工作。
RMaps:把多个 Map 的批量操作提升为一等能力
过去使用 Redis Hash 时,应用通常围绕单个 RMap 展开操作。当业务需要同时读取或处理多个 Map,例如批量加载一组用户配置、租户状态或设备属性,代码容易出现循环调用。
RMaps 的加入面向的正是这类跨 Map 批处理场景。它有两个直接收益:
- 业务代码可以明确表达“这是一组 Map 的操作”,而不是把单对象调用包在循环里。
- 客户端有机会减少重复交互以及批处理样板代码。
不过,批量 API 不等于自动获得事务语义。采用时需要确认失败行为、返回值结构、集群槽位限制以及单批数据规模。尤其是在 Redis Cluster 中,不同键可能落在不同槽位,批处理并不必然意味着单次原子执行。
由于摘要没有给出 RMaps 的完整方法签名,可以这样实践:先锁定 4.7.0 依赖,再根据该版本 Javadoc 将现有的循环读取改成批量接口,并通过集成测试验证缺失键、部分失败和集群部署下的行为。不要根据其他版本的示例直接推断方法名。
Circular Buffer 与 RRingBuffer 的职责边界
环形缓冲区适合容量固定、旧数据可以被覆盖或淘汰的场景,例如:
- 保存设备最近 100 次状态上报;
- 保留任务最近一批执行结果;
- 存放用于诊断的短期事件窗口;
- 为监控页面提供最近发生的告警。
4.7.0 新增了基于数组的 Circular Buffer 对象,同时增强了已有的 RRingBuffer。其中,readNewest() 和 readOldest() 让调用方可以从“最新”或“最旧”的方向读取元素,不必先拉取整个缓冲区再在 JVM 中切片。
选择数据结构时,先回答三个问题:容量是否固定、写满后的数据如何处理、读取是否会删除元素。读取方法通常意味着观察数据,而不是消费数据;如果业务要求元素只能被处理一次,应评估阻塞队列、可靠队列或流式结构,而不是把环形缓冲区当成消息队列。
可以这样实践:运行一个 RRingBuffer 示例
下面示例使用 Maven、Java 17 和本地 Redis。运行前把 Redis 地址、用户名或密码改成实际环境配置。示例演示容量限制,以及从新旧两个方向读取记录。
创建 pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>redisson-ring-buffer-demo</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
<dependencies>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>4.7.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<mainClass>example.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
创建 src/main/java/example/App.java:
package example;
import org.redisson.Redisson;
import org.redisson.api.RRingBuffer;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
public final class App {
public static void main(String[] args) {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
try {
RRingBuffer<String> events = redisson.getRingBuffer("demo:recent-events");
events.delete();
events.trySetCapacity(3);
events.add("job-101:started");
events.add("job-101:running");
events.add("job-101:succeeded");
events.add("job-102:started");
System.out.println("oldest two = " + events.readOldest(2));
System.out.println("newest two = " + events.readNewest(2));
System.out.println("size = " + events.size());
} finally {
redisson.shutdown();
}
}
}
启动 Redis 并运行示例:
docker run --rm --name redisson-demo-redis -p 6379:6379 -d redis:7
mvn -q compile exec:java
由于容量设置为 3,写入第 4 条记录后,缓冲区仍只保留有限数量的元素。具体顺序和覆盖行为应以 4.7.0 API 文档及实际测试结果为准,尤其不要仅凭打印顺序设计关键业务逻辑。
升级时重点检查什么
从旧版升级到 4.7.0 时,不建议因为出现了新对象就立即替换所有现有实现。更稳妥的做法是从调用密集、边界清晰的场景开始:
- 用真实 Redis 拓扑执行集成测试,包括单机、哨兵或集群环境。
- 对比批量操作前后的 Redis 请求数、延迟和序列化开销。
- 为环形缓冲区明确容量、溢出策略、保留时间和读取方向。
- 验证
readNewest()、readOldest()是否符合业务期望,并确认读取会不会改变数据。 - 检查新依赖与 Spring Boot、Netty、编解码器及 Java 运行时版本的兼容性。
- 限制单批数据量,避免大结果集占满 JVM 堆或阻塞网络事件循环。
RMaps 适合减少跨 Map 操作的样板代码,Circular Buffer 和增强后的 RRingBuffer 则适合表达有界历史窗口。真正决定是否采用它们的,不是 API 看起来是否简洁,而是数据一致性、内存上限、集群行为和故障语义是否与业务约束一致。