代码之家  ›  专栏  ›  技术社区  ›  ScottSummers

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

  •  1
  • ScottSummers  · 技术社区  · 7 年前

    我希望存储在redis缓存中的数据在给定时间段后自动从缓存中清除,而无需对其调用delete方法。在此POC中,我将TTL设置为60秒。我曾尝试在缓存管理器中使用API setDefaultExpirement、setExpires进行设置,并在RedisTemplate中使用API expire进行设置。到目前为止,没有一个解决方案对我有效。

    @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));
        }
    }
    

    请给我指出正确的方向。非常感谢您的帮助。

    2 回复  |  直到 7 年前
        1
  •  3
  •   Mạnh Quyết Nguyễn    7 年前

    在代码中:

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

    因此,基本上您希望使散列中的密钥过期。但不幸的是,这不能使用标准的redis命令来完成。

    Reference

        2
  •  1
  •   Dherik    7 年前

    如果要在一段时间后使缓存过期, usually the people use 这个 Scheduled 具有 CacheEvict 。因此,调度程序在一段时间后运行并调用缓存逐出。

    每个示例:

    @Cacheable(value = "parameters-all")
    public List<ParametroResponse> getAll() {
        return repository.findAll();
    }
    
    @CacheEvict(allEntries = true, cacheNames = { "parameters-all" })
    @Scheduled(fixedDelayString = "${spring.cache.redis.ttl}")
    public void cacheEvict() {
        log.info("parameters-all cache evict");
    }