When profiling an application it came up that Redis is impacting the execution times because there are many sleeps in threads. I need to implement two levels of cache or think about solution of this problem.
I would like to have two levels of caches:
- L1 - local for each instance of deployment,
- L2 - cache global for all instances of same deployment,
The solution that I came up with is:
- Create two CacheManagers (CaffeineCacheManager and RedisCacheManager),
- Initialize same caches for each cache manager,
- Use annotation @Caching with cacheable={} to use two caches,
@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);
}
The structure of classes is similar to: CachedService (annotations here) -> NonCachedService
The problem I am facing:
I wanted to have it working in flow (yes - works/n - not working):
- [ y ] data is fetched and then cached to both caches Redis and local - this works
- [ y ] if data exists in local cache do not move it to redis - this works
- [ y ] if any of caches contains the data it will be fetched from cache
- [ n ] if data exists in Redis, move it to local - this does not work
Modification of @Caching annotation to have put={} where it would put values into local cache is making whole cache not working.
@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);
}
- Do you know any spring-ready solutions to work with two levels of cache?
- I've read about local caching with Redis but it does not mean anything similar to my case (it's just the standard redis use case),
- I am left only with double-layered services structure to achieve this goal? Similar to CachedLocal -> CachedRedis -> NonCached