You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring @Cacheable如何适配Redis读写分离副本?

实现Redis缓存读写分离(主从连接)并兼容@Cacheable注解

完全可以实现,核心思路是配置两个独立的CacheManager,分别绑定主节点(读写)和从节点(只读)的连接工厂,再通过缓存注解指定对应的CacheManager来区分读写操作。

1. 配置两个Lettuce连接工厂

先定义主节点(用于缓存写/更新/删除)和从节点(仅用于缓存读)的连接工厂Bean:

@Configuration
@EnableCaching
public class CacheConfiguration extends CachingConfig {

    // 主节点连接工厂(读写),可沿用原有自动配置参数或自定义配置
    @Bean("lettuceMasterConnectionFactory")
    public LettuceConnectionFactory lettuceMasterConnectionFactory(RedisProperties redisProperties) {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisProperties.getHost(), redisProperties.getPort());
        config.setPassword(RedisPassword.of(redisProperties.getPassword()));
        return new LettuceConnectionFactory(config);
    }

    // 从节点连接工厂(只读),配置副本节点地址
    @Bean("lettuceSlaveConnectionFactory")
    public LettuceConnectionFactory lettuceSlaveConnectionFactory() {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("redis-slave-host", 6379);
        config.setPassword(RedisPassword.of("slave-password"));
        return new LettuceConnectionFactory(config);
    }

    // 后续CacheManager配置...
}

2. 配置两个对应的CacheManager

分别创建主从对应的CacheManager,保留原有TTL配置逻辑:

// 主节点CacheManager,用于写/更新/删除操作
@Bean("masterCacheManager")
public CacheManager masterCacheManager(@Qualifier("lettuceMasterConnectionFactory") LettuceConnectionFactory masterFactory) {
    RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig();
    return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(masterFactory)
            .cacheDefaults(defaultConfig)
            .withCacheConfiguration("myCache", defaultConfig.entryTtl(Duration.ofMinutes(5)))
            .withCacheConfiguration("someOtherCache", defaultConfig.entryTtl(Duration.ofMinutes(10)))
            .build();
}

// 从节点CacheManager,仅用于读操作
@Bean("slaveCacheManager")
public CacheManager slaveCacheManager(@Qualifier("lettuceSlaveConnectionFactory") LettuceConnectionFactory slaveFactory) {
    RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig();
    return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(slaveFactory)
            .cacheDefaults(defaultConfig)
            .withCacheConfiguration("myCache", defaultConfig.entryTtl(Duration.ofMinutes(5)))
            .withCacheConfiguration("someOtherCache", defaultConfig.entryTtl(Duration.ofMinutes(10)))
            .build();
}

3. 修改缓存注解指定CacheManager

在业务方法上,给@Cacheable(读操作)指定从节点的CacheManager;写/更新/删除操作(如@CachePut、@CacheEvict)指定主节点的CacheManager:

// 读操作:使用从节点CacheManager
@Cacheable(cacheNames = "myCache", key = "#token", cacheManager = "slaveCacheManager")
public String getUserByToken(String token) {
    return externalService.getUserFromToken(token);
}

// 更新缓存操作:使用主节点CacheManager
@CachePut(cacheNames = "myCache", key = "#token", cacheManager = "masterCacheManager")
public String updateUserToken(String token, UserInfo userInfo) {
    externalService.updateUser(token, userInfo);
    return userInfo.toString();
}

// 删除缓存操作:使用主节点CacheManager
@CacheEvict(cacheNames = "myCache", key = "#token", cacheManager = "masterCacheManager")
public void invalidateUserToken(String token) {
    externalService.invalidateToken(token);
}

补充说明

  • 若希望大部分读操作默认用从节点,可给slaveCacheManager添加@Primary注解,未指定cacheManager的@Cacheable会自动使用从节点;写操作需显式指定masterCacheManager。
  • 确保从节点Redis配置为只读模式,避免误写操作。

内容的提问来源于stack exchange,提问作者Alexis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 20:06:19