Redisson的分布式集合

介绍

Redisson 是 Redis Java 客户端和实时数据平台。它为使用 Redis 提供了更方便、更简单的方法。Redisson 对象提供了关注点分离功能,可让你专注于数据建模和应用逻辑。

在Java中,为我们提供了丰富的集合类,如ListSetMap 等,这些集合类在单机应用或单个JVM进程中是非常强大和有效的工具。然而,在分布式系统下,数据需要在多个JVM进程或节点之间共享和同步。为实现这一目标Redisson提供了许多分布式集合实现,如RListRSetRMap等,这些集合类能够在多个Redis节点之间无缝地共享数据。通过使用Redisson,开发者可以像使用传统Java集合类一样,在分布式系统中进行数据的增删改查操作,而无需担心数据在不同节点之间的同步和一致性问题。

Code

1. Map集合

基于 Redis 的 Java 分布式 RMap 对象实现了 ConcurrentMap 接口。该对象是完全线程安全的。

java 复制代码
public interface RMap<K, V> extends ConcurrentMap<K, V>, ...{}
  • 同步存数据
java 复制代码
RMap<String, User> map = redisson.getMap("user-list");
User preValue = map.put("1", new User(2L, "张三2", 22)) ;
User value = map.putIfAbsent("2", new User(2L, "李四", 33));
  • 快速存数据 如果你不需要返回上一个值(旧值)建议使用相应fast* 方法
java 复制代码
RMap<String, User> map = redisson.getMap("user-list");
map.fastPut("1", new User(2L, "张三2", 22));
map.fastPutIfAbsent("2", new User(2L, "李四", 33));
map.fastRemove("1") ;

以上操作不会返回对应key之前的旧值。

  • 异步存数据
java 复制代码
RFuture<User> f1 = map.putAsync("1", new User(2L, "张三2", 22)) ;
RFuture<Boolean> f2 = map.fastPutAsync("2", new User(2L, "李四", 33)) ;
RFuture<Long> f3 = map.fastRemoveAsync("2") ;
  • Map集合中key绑定Lock
java 复制代码
RMap<String, User> map = redisson.getMap("user-list") ;
RLock lock = map.getLock(key) ;
lock.lock() ;
try {
  System.out.printf("当前线程: %s, 当前时间: %d%n", Thread.currentThread().getName(), System.currentTimeMillis()) ;
  TimeUnit.SECONDS.sleep(3) ;
} finally {
  lock.unlock() ;
}
  • 本地缓存

用于加快读取操作速度,避免网络往返。它在 Redisson 端缓存地图条目,执行读取操作的速度是普通实现的 45 倍。支持本地缓存的地图对象实现了RLocalCachedMap,它扩展了 java.util.concurrent.ConcurrentMap 接口。该对象是完全线程安全的。

java 复制代码
// 配置缓存策略
final LocalCachedMapOptions<String, User> LOCAL_CACHE = LocalCachedMapOptions.<String, User>defaults()
      // 缓存大小
      .cacheSize(200)
      // 缓存模式
      .storeMode(StoreMode.LOCALCACHE_REDIS)
      // 删除策略
      .evictionPolicy(EvictionPolicy.LRU) ;
// 获取指定key本地缓存      
RLocalCachedMap<String,User> localCachedMap = redisson.getLocalCachedMap("user-list", LOCAL_CACHE) ;
User user = localCachedMap.get("1") ;

本地缓存实例对象同样支持fast*及异步方式,这里不再赘述。

  • 事件监听

Redisson 允许为每个 RMap 对象绑定监听器,RMap 对象允许跟踪数据上的跟踪事件。如下表,监听类及事件

java 复制代码
RMap<String, User> map = redisson.getMap("user-list");
int deletedListener = map.addListener(new DeletedObjectListener() {
  @Override
  public void onDeleted(String name) {
    // ...
  }
});
int expredListener = map.addListener(new ExpiredObjectListener() {
  @Override
  public void onExpired(String name) {
    // ...
  }
});
int putListener = map.addListener(new MapPutListener() {
  @Override
  public void onPut(String name) {
    // ...
  }
});
int removeListener = map.addListener(new MapRemoveListener() {
  @Override
  public void onRemove(String name) {
    // ...
  }
});
// 删除监听器
map.removeListener(listenerId) ; // removeListener, putListener ...

2. Set集合

基于 Redis 的 Java Set 对象实现了 java.util.Set 接口。该对象完全线程安全。通过元素状态比较保持元素的唯一性。Redis 将集合大小限制为 4 294 967 295(2^32-1) 个元素。Redis 使用序列化状态检查值的唯一性,而不是值的 hashCode()/equals() 方法。

java 复制代码
public interface RSet<V> extends Set<V>,...{}
  • 基本操作
java 复制代码
RSet<User> set = redisson.getSet("user-set");
set.add(new User(1L, "张三", 33)) ;
set.add(new User(2L, "李四", 55)) ;

RSet使用Set集合。与RMap一样,RSet也支持同步异步方式操作数据

java 复制代码
RFuture<Boolean> f1 = set.addAsync(new User(1L, "张三", 33)) ;
RFuture<Boolean> f2 = set.addAsync(new User(2L, "李四", 55)) ;
  • 绑定Lock操作
java 复制代码
RSet<User> set = redisson.getSet("user-set") ;
RLock lock = set.getLock(new User(1L, "张三", 33)) ;
lock.lock() ;
try {
  // ...
} finally {
  lock.unlock() ;
}
  • 删除策略

当前的Redis实现没有设置值删除功能。因此,过期的数据会被org.redisson.eviction.EvictionScheduler清除。它一次性删除300个过期条目。如果clean task每次删除300项,它将每秒执行一次(最小执行延迟)。但如果当前的过期值小于前一个,则执行延迟将增加1.5倍。

java 复制代码
RSetCache<User> set = redisson.getSetCache("user-set") ;
set.add(new User(3L, "阴阳路", 66), 180L, TimeUnit.SECONDS) ;
  • 事件监听

与Map一样Set也有对应的事件监听,详细查看Map中对应的说明。

  • Set排序

基于 Redis 的 Java 分布式 SortedSet 实现了 java.util.SortedSet 接口。该对象线程安全。它使用比较器对元素进行排序并保持唯一性。对于字符串数据类型,建议使用 LexSortedSet 对象,以提高性能。

java 复制代码
RSortedSet<Integer> set = redisson.getSortedSet("set-sort") ;
// 这里不可以写成lambda表达式:(o1, o2) -> Integer.compare(o1, o2)
set.trySetComparator(new Comparator<Integer>() {
  @Override
  public int compare(Integer o1, Integer o2) {
    return o1 > o2 ? 1 : (o1 < o2 ? -1 : 0)  ;
  }
}) ;
set.add(3) ;
set.add(1) ;
set.add(2) ;

3. List集合

基于 Redis 的 Java 分布式 RList 对象实现了 java.util.List 接口。它按插入顺序保存元素。

它有 Async、Reactive 和 RxJava3 接口。Redis 限制列表大小为 4 294 967 295(2^32-1) 个元素。

java 复制代码
public interface RList<V> extends List<V>, ... {}
  • 基本操作
java 复制代码
RList<User> list = redisson.getList("user-list");
User user = new User(1L, "张三", 10);
list.add(user) ;
User ret = list.get(0) ;
System.out.println("ret = " + ret) ;
list.remove(user) ;
  • 事件监听
java 复制代码
RList<User> list = redisson.getList("user-list") ;
list.addListener(new ExpiredObjectListener() {
  @Override
  public void onExpired(String name) {
    // ...
  }
}) ;
// 其它事件
/**
 * DeletedObjectListener
 * ListAddListener
 * ListInsertListener
 * ListSetListener
 * ListRemoveListener
 * ListTrimListener
 */

4. Queue队列

基于 Redis 的 Java 分布式无界队列对象,实现了 java.util.Queue 接口。该对象是完全线程安全的。它有 Async、Reactive 和 RxJava3 接口。

java 复制代码
public interface RQueue<V> extends Queue<V>, ... {}
  • 基本操作
java 复制代码
RQueue<User> queue = redisson.getQueue("user-queue");
queue.add(new User()) ;
// 获取但不删除
User u1 = queue.peek() ;
// 获取并删除
User u2 = queue.poll() ;
  • 事件监听
java 复制代码
RQueue<User> queue = redisson.getQueue("user-queue") ;
queue.addListener(new ExpiredObjectListener() {
  @Override
  public void onExpired(String name) {
    // ...
  }
}) ;
// 其它事件
/**
 * ListAddListener
 * ListInsertListener
 * ListRemoveListener
 */

5. 阻塞队列

基于Redis 的Java 分布式无界RBlockingQueue 对象,实现了 java.util.concurrent.BlockingQueue接口。该对象是完全线程安全的。它有 Async、Reactive 和 RxJava3 接口。

java 复制代码
public interface RBlockingQueue<V> extends BlockingQueue<V>, ... {}
  • 基本操作
java 复制代码
RBlockingQueue<User> queue = redisson.getBlockingQueue("user-blockqueue");
queue.offer(new User(1L, "哈哈", 22)) ;
// queue.offer(new User(2L, "嘿嘿", 33)) ;

User u1 = queue.peek() ;
User u2 = queue.poll() ;
// 这里会被阻塞,最多等待10s队列中有元素则直接返回
User u3 = queue.poll(10, TimeUnit.SECONDS) ;

6. 有界阻塞队列

java 复制代码
RBoundedBlockingQueue<SomeObject> queue = redisson.getBoundedBlockingQueue("user-capacity-queue");
// 设置容量大小
queue.trySetCapacity(2);

queue.offer(new User(1L, "张三", 20));
queue.offer(new User(2L, "李四", 10));
相关推荐
llz_1125 小时前
web-第二次课后作业
前端·后端·web
红尘散仙11 小时前
我把终端小说阅读器接上了 AI Agent:TRNovel 现在能用 skill 生成书源了
人工智能·后端·rust
卷毛的技术笔记12 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
会编程的土豆13 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
喵个咪13 小时前
GoWind Toolkit Go后端代码生成 完整全流程实战
后端·go·orm
basketball61613 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang
qq_25183645713 小时前
SpringBoot+Vue 共享电池柜管理系统 完整实现 前后端分离项目实战 完整代码
vue.js·spring boot·后端
zhangxingchao14 小时前
AI 大模型核心六:量化、Workflow 与 Agent、多轮 RAG
前端·人工智能·后端
IT_陈寒15 小时前
Vite打包时遇到的坑,原来问题出在这里
前端·人工智能·后端
ayqy贾杰16 小时前
基层管理的三板斧,在AI时代行不通了
前端·后端·团队管理