我有一个 Spring Boot (2.3.1.RELEASE) 应用程序,它使用 Redis Sentinel 进行缓存。 这是我的 Sentinel 连接配置:
@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);
}
这是我的缓存管理器配置:
@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();
}
从缓存的角度来看,一切正常。
但是,如果我在 io.lettuce.core.protocol.CommandHandler 内打开调试日志,我会发现它始终连接到同一节点(主节点)。我可以通过查看节点上的日志来确认这一点。
我在网上到处查看,这似乎是正确的配置。
这引出了我的问题:
- 是否可以将 Spring 缓存抽象配置为仅使用主节点进行写入,使用从属节点进行读取?
这个期望是否有效?或者这就是 Sentinel 应该使用的方式(所有请求都发送到 master)?
最佳答案
是的,可以做到。
来自Spring Data Redis Docs - 10.4.4. Write to Master, Read from Replica :
It is said that Spring Data Redis provides a Redis Master/Replica setup which not only allows data to be safely stored at more nodes but also allows reading data from replicas while pushing writes to the master by using Lettuce.
为此,您必须更新配置类中的 redisConnectionFactory()
方法:
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.readFrom(ReadFrom.REPLICA_PREFERRED)
.build();
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, clientConfig);
}
关于java - 使用 Redis Sentinel 的 Spring Boot 缓存始终连接到主节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64809960/