两级缓存(Redis+Caffeine)

wi3ka0sx  于 2022-10-08  发布在  Redis
关注(0)|答案(1)|浏览(194)

在分析应用程序时,发现Redis正在影响执行时间,因为线程中有很多休眠。我需要实现两级缓存,或者考虑这个问题的解决方案。

  • 我希望有两个级别的缓存*:

  • L1-本地部署的每个示例,

  • L2-同一部署的所有示例的全局缓存,

我提出的解决方案是

  • 创建两个CacheManager(CaffeineCacheManager和RedisCacheManager)。
  • 为每个缓存管理器初始化相同的缓存,
  • 使用带有cacheable={}的注解@caching使用两个缓存,
@Caching(cacheable = {
            @Cacheable(cacheNames = CacheConfiguration.HELLO_WORLD),
            @Cacheable(cacheNames = CacheConfiguration.HELLO_WORLD, cacheManager = "cacheManagerRedis")
    })
    public String generate(String name)
    {
        log.info("  Cached method call...");
        return helloWorldService.generate(name);
    }

类的结构类似于:CachedService(此处注解)->NonCachedService

  • 我面临的问题*:**

我想让它在流中工作(是-工作/n-不工作):

  • [y]数据被获取,然后缓存到Redis和本地缓存-这是可行的
  • [y]如果数据存在于本地缓存中,请不要将其移动到Redis-这是可行的
  • [y]如果任何缓存包含该数据,则将从缓存中提取该数据
  • [n]如果Redis中存在数据,请将其移动到本地-这不起作用

将@Caching注解修改为**PUT={}**将值放入本地缓存的位置会导致整个缓存无法工作。

@Caching(cacheable = {
            @Cacheable(cacheNames = CacheConfiguration.HELLO_WORLD),
            @Cacheable(cacheNames = CacheConfiguration.HELLO_WORLD, cacheManager = "cacheManagerRedis")
    }, put = {
            @CachePut(cacheNames = CacheConfiguration.HELLO_WORLD),
    })
    public String generate(String name)
    {
        log.info("  Cached method call...");
        return helloWorldService.generate(name);
    }
  • 您是否知道可以使用两级缓存的Spring-Ready解决方案?
  • 我读到过Redis的本地缓存,但它与我的情况没有任何相似之处(这只是标准的Redis用例),
  • 我只剩下双层服务结构来实现这个目标?类似CachedLocal->CachedRedis->非缓存
dpiehjr4

dpiehjr41#

对于其他正在寻找这一功能的人,我能够实现Ankit建议的CacheInterceptor。

示例:

public class RedisMultiCacheInterceptor extends CacheInterceptor {

@Autowired
private CacheManager caffeineCacheManager;

@Override
protected Cache.ValueWrapper doGet(Cache cache, Object key) {
    //Get item from cache
    var superGetResult = super.doGet(cache, key);

    if (superGetResult == null) {
        return superGetResult;
    }

    //If retrieved from Redis, check if it's missing from caffeine on local and add it
    if (cache.getClass() == RedisCache.class) {
        var caffeineCache = caffeineCacheManager.getCache(cache.getName());

        if (caffeineCache != null) {
            caffeineCache.putIfAbsent(key, superGetResult.get());
        }
    }

    return superGetResult;
}

}

相关问题