掘金 后端 ( ) • 2024-04-28 11:15

关于https://juejin.cn/post/7361328537678757923 (基于Redission高级应用5-RLocalCachedMapt原理及实战应用) 中提到RLocalCachedMapt的使用,有老铁提出该map里面的每个key都开一个定时任务监听,map的key变多会导致内存溢出,由此想着如何优化上篇文章内容: RLocalCachedMapRLocalCachedMap 是 Redisson 提供的一个本地缓存客户端,它在本地存储了远程 Redis 中的数据副本,以减少网络开销和提高性能。然而,如果不正确使用,它可能会导致资源消耗问题,如您提到的,如果键值对非常多,每个键都设置了过期监听器,就可能导致大量的定时任务占用内存,最终导致OOM(内存溢出)。

为了避免RLocalCachedMap的这个缺点,可以采取以下策略:

  1. 限制本地缓存大小:通过配置localCacheSize参数限制本地缓存的大小,以避免过多的键值对被缓存到本地。

  2. 合理设置过期时间:如果所有键都设置了过期时间,可以考虑增加过期时间或者不为每个键设置监听器,而是使用定时任务批量清理过期键。

  3. 使用弱引用:配置RLocalCachedMap使用弱引用存储键值对,这样一旦内存不足,这部分内存可以被垃圾收集器回收。

  4. 监听器优化:如果需要监听过期事件,可以考虑使用单个监听器来处理多个键的事件,而不是为每个键单独设置监听器。

  5. 按需使用:只对热点数据使用本地缓存,不是所有数据都需要本地缓存。

  6. 缓存清理策略:定期清理不常用或低优先级的缓存数据,可以手动或使用定时任务。

  7. 内存监控:实施内存使用监控,当达到一定阈值时触发报警或自动清理策略。

  8. 备选方案:如果RLocalCachedMap的缺点难以克服,可以考虑使用其他缓存策略,如只使用Redis缓存,或者采用其他本地缓存库(如Caffeine)与Redis缓存组合使用。 请参考:https://juejin.cn/post/7361255930648526848

这是一个配置RLocalCachedMap的例子,它使用了一些上述策略: 基于Redission高级应用5-RLocalCachedMapt原理及实战应用

Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");

// 创建RLocalCachedMap的配置对象
LocalCachedMapOptions<String, SomeObject> localCachedMapOptions = LocalCachedMapOptions.<String, SomeObject>defaults()
    .cacheSize(1000) // 限制本地缓存的大小
    .timeToLive(60 * 60 * 1000) // 设置默认的存活时间
    .maxIdle(30 * 60 * 1000) // 设置最大空闲时间
    .evictionPolicy(LocalCachedMapOptions.EvictionPolicy.LFU) // 设置淘汰策略
    .weakEntries(true); // 使用弱引用

// 使用配置创建RLocalCachedMap
RLocalCachedMap<String, SomeObject> localCachedMap = redissonClient.getLocalCachedMap("myMap", localCachedMapOptions);

在这个配置中,我们限制了本地缓存的大小为1000个键值对,设置了默认的存活时间和最大空闲时间,并且启用了弱引用来存储条目。

总之,RLocalCachedMap可以显著提升性能,但必须谨慎使用并合理配置以避免资源消耗问题。