I have a Spring Boot (2.3.1.RELEASE) app that has caching with Redis Sentinel.
This is my configuration for the Sentinel connection:
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
.master(redisProperties.getSentinel().getMaster());
redisProperties.getSentinel().getNodes().forEach(s -> sentinelConfig.sentinel(s, redisProperties.getPort()));
sentinelConfig.setPassword(RedisPassword.of(redisProperties.getPassword()));
return new LettuceConnectionFactory(sentinelConfig);
}
And this is my caching manager configuration:
@Bean
public RedisCacheManager cacheManager() {
Map<String, RedisCacheConfiguration> cacheConfigs = new HashMap<>();
cacheConfigs.put("cache1", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(ttlMinutes)));
cacheConfigs.put("cache2", RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(ttlMinutes)));
return RedisCacheManager.builder(redisConnectionFactory())
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(ttlMinutes)))
.withInitialCacheConfigurations(cacheConfigs)
.transactionAware()
.build();
}
Everything works fine from caching perspective.
However, If I turn on debug logs inside the io.lettuce.core.protocol.CommandHandler
, I see that it is always connecting to the same node (master). Which I can confirm by looking at the logs on the node.
Everywhere I look online, this seems like the correct configuration.
This brings me to my question:
- Is it possible to configure the Spring caching abstraction to use the master node only for writes and the slave nodes for reads?
Is this expectation even valid? Or this is the way Sentinel is supposed to be used (all requests go to master)?
2
Answers
Yes, it can be done.
From Spring Data Redis Docs – 10.4.4. Write to Master, Read from Replica :
For this, you have to update
redisConnectionFactory()
method in the configuration class :if you want to write master and read only from all slaves(replicas), you can use below configuration.
These configurations include connection pooling,write to master and read from all slave nodes with round-robin load balancing.
you should import new lettuce core version for load balance read mode(ReadFrom.ANY_REPLICA), it will come with spring-boot 2.4.0
pom.xml