I am connecting to Google Cloud Platform memorystore Redis with Read replica enabled. It exposes 2 endpoints:
- Primary for writing to Redis Cache
- Read Replica for reading from Redis Cache
I have created 2 Cache managers to connect to these endpoints. Now using @Cacheable
annotation I can only specify one cache manager at a time. I need to specify a specific Cache manager for reading from cache and another one to write to the cache. I figured, I need to extend the behavior of @Cacheable
to add a secondary Cache manager which can be used to write to the primary endpoint.
Is it possible to do so in Spring and if so, what is the process to achieve this behavior. Any pointers will be greatly appreciated.
2
Answers
This is how I was able to modify the @Cacheable behavior:
unless
attribute inside @Cacheable as follows:@Cacheable(unless="isReadReplicaEnabled") public Data getData()
@CachePut
in new class to use new cache manager which connects to Primary redis instance,as below:@CachePut(cacheManager ="primaryCacheManager") public void writeToCache()
writeToCache
method if the read replica is enabled:if(isReadReplicaEnabled()){ writeToCache(); }
https://github.com/lettuce-io/lettuce-core/wiki/ReadFrom-Settings
With Lettuce (but probably others as well) you can set a flag
.readFrom(ReadFrom.REPLICA)
The factory will cleverly fetch the slave / read replica from the
INFO
command and issue reads to it automatically.Note that if you use AWS ElastiCache Redis, their
INFO
command only returns a slave’s private IP that will be unreachable by your app..The only solution is to create your own
LettuceConnectionFactory
with aRedisStaticMasterReplicaConfiguration
where you will be able to set your master and replica node.You won’t be able to use the Spring’s auto
LettuceConnectionConfiguration
because they don’t createRedisStaticMasterReplicaConfiguration
in there.