1
回答
redis的一些入门问题~数据丢失问题以及java中该如何配合业务简单使用?
极速云服务器,低至1.04元/天>>>   

 

    public List<Cache> getCache(String type){
        String cacheKey = "cache" + type
        if (redisUtil.getCacheList(cacheKey!=null) {
            return redisUtil.getCacheList(cacheKey );
        }

	===业务===
  
        redisUtil.setCacheList(cacheKey , cacheList);
        return cacheList;
    }

这是一个service里面取缓存的写法,感觉特别麻烦(如果业务更复杂)

先说说数据丢失的问题,感觉是我哪里配置错了吧?

情况如下:

    第一次进来,正确地缓存了。

    第二次进来,正确地拿到值了。拿到值后,缓存的值丢失了~而且并不是值过期了,而是直接没了

    第三次进来,又只能去取数据库了。

    public <T> List<T> getCacheList(String key) {
        List<T> dataList = new ArrayList<T>();
        ListOperations<String, T> listOperation = redisTemplate.opsForList();
        Long size = listOperation.size(key);

        for (int i = 0; i < size; i++) {
            dataList.add((T) listOperation.leftPop(key));
        }

        return dataList;
    }

这是取缓存的方法

@Configuration
@PropertySource(value = "classpath:/application.properties")
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.timeout}")
    private int timeout;
    @Value("${spring.redis.password}")
    private String password;

    @Bean
    public KeyGenerator wiselyKeyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setHostName(host);
        factory.setPort(port);
        factory.setTimeout(timeout); //设置连接超时时间
        factory.setPassword(password);
        return factory;
    }

    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        // Number of seconds before expiration. Defaults to unlimited (0)
        cacheManager.setDefaultExpiration(60); //设置key-value超时时间
        return cacheManager;
    }

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口
        template.afterPropertiesSet();
        return template;
    }

    private void setSerializer(StringRedisTemplate template) {
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setValueSerializer(jackson2JsonRedisSerializer);
    }
}

这是配置文件

ps:当然还有可能是redis本身的配置有问题!我记得缓存时之前一直报

MISCONF Redis is configured to save RDB snapshots, but it is currently not  able to persist on disk 

看了网上说是内存不足问题?

    总之用了一个傻办法

    config set stop-writes-on-bgsave-error no

    这样肯定是不对的,然而总算可以用了,接着就出现了上面的情况。

然而,用spring的注解@Cacheable却完全没有这个问题!!

这是为什么呢...?

举报
Anur
发帖于2个月前 1回/85阅
顶部