尽管设置了 TTL,但 Redis 缓存未被清除

标签 redis spring-cache spring-data-redis redis-cache

我想让存储在redis缓存中的数据在给定时间后自动从缓存中清除,而不需要调用它的delete方法。在此 POC 中,我将 TTL 设置为 60 秒。我已经尝试使用 API setDefaultExpiration、setExpires 在缓存管理器中设置它,并使用 API 过期在 RedisTemplate 中设置它。到目前为止,没有一种解决方案对我有用。

@Configuration
public class RedisServerConfig extends CachingConfigurerSupport {
    @Bean
    public RedisTemplate<String, String> redisTemplate() {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
    @Bean
    public CacheManager cacheManager(RedisTemplate<String, String> redisTemplate) {
        RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
        redisCacheManager.setUsePrefix(true);
        redisCacheManager.setCacheNames(cacheNames);
        redisCacheManager.setTransactionAware(true);
        redisCacheManager.setLoadRemoteCachesOnStartup(true);

        // Using setDefaultExpiration
        //redisCacheManager.setDefaultExpiration(60);

        // Using setExpires
        //Map<String, Long> expires = new HashMap<>();
        //cacheNames.stream().forEach(name->expires.put(name, 60L));
        //redisCacheManager.setExpires(expires);
        return redisCacheManager;
    }
    @Bean
    public RedisConnectionFactory connectionFactory() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(maxTotal);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        poolConfig.setTestWhileIdle(true);
        poolConfig.setMaxWaitMillis(secondsToWait);
        JedisConnectionFactory factory = new JedisConnectionFactory(sentinelConfig(), poolConfig);
        factory.setUsePool(true);
        factory.setPassword(redisPassword);
        factory.setPort(redisPort);

        return factory;
    }
}

在使用的redis仓库中,

@Repository
public class RedisRepository {
    private static final Logger logger = LoggerFactory.getLogger(RedisRepositoryImpl.class);
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    public void saveSharedSecret(String customerNumber, String sharedSecret) {
        redisTemplate.opsForHash().put(MfaConstants.REDIS_SHAREDSECRET_REGION, myKey, myValue);
        redisTemplate.expire(myKey, 1, TimeUnit.MINUTES);

        // The timeOut obtained here is zero
        logger.info("myKey: [{}], timeOut: [{}]", myKey, redisTemplate.getExpire(myKey, TimeUnit.SECONDS));
    }
}

请指点我正确的方向。感谢您的帮助。

最佳答案

在您的代码中:

redisTemplate.opsForHash().put(MfaConstants.REDIS_SHAREDSECRET_REGION, myKey, myValue);
redisTemplate.expire(myKey, 1, TimeUnit.MINUTES);

所以基本上你想让散列中的键过期。但不幸的是,它不能使用标准的 redis 命令来完成。

Reference

关于尽管设置了 TTL,但 Redis 缓存未被清除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50334232/

相关文章:

django - 无法在 debug = False(生产)中使用 Django 启动工作进程 Celery 任务

java - 如何从java将变量传递给lua脚本? ( io.生菜.core )

aspectj - Spring 的 AspectJ 模式缓存与 AspectJ 模式事务

Redis/.rdb 文件的限制

node.js - 在哪里运行 redis -sentinel

java - 响应式(Reactive)应用程序中的 Spring Cache

java - 使用 Caffeine 在 Spring Boot 中进行缓存

通过具有过去时间戳的 EXPIREAT 命令的 Redis key 过期事件

spring-boot - Spring-找到多个Spring Data模块,进入严格的存储库配置模式

spring-mvc - 在spring mvc项目中使用@CachePut,但是在redis中获取key和value两个单独的数据