美文网首页
多级缓存之一:Redis集中式缓存应用

多级缓存之一:Redis集中式缓存应用

作者: YoSaukit | 来源:发表于2019-07-15 21:00 被阅读0次

    接上一篇分布式会话实现(Springboot+redis),完成了用户登录验证成功后将对应的登录信息和登录凭证保存到redis。
    本篇以保存商品详情页信息为例,完成redis商品详情的存取的应用。
    缓存的数据库中间件,相当于nosql数据库,只能用key-value查询。
    集中式的管理缓存
    ○ 单机版
    单个业务结点的redis挂了业务会受影响
    ○ sentinal哨兵模式
    用redis sentinal来管理(心跳机制)redis master和redis slave,应用程序只需要感知redis sentinal
    ○ 集群cluster模式
    以上三种模式都被spring-data-redis和jedis jar支撑,客户端只需要做配置即可启用。
    三种设计模式的性能瓶颈都是在水平拓展后的容量问题上,整个设计思路实际上不变。

    1. 未序列化使用redis

     key保存item_id,value保存itemModel
    

    ItemController.java

    ```
    ...
    //根据商品的id到redis内获取
    ItemModel itemModel = (ItemModel) redisTemplate.opsForValue().get("item_"+id);
    //若redis内不存在对应的itemModel,则访问下游service
        if (itemModel == null){
            itemModel = itemService.getItemById(id);
            //设置itemModel到redis内
            redisTemplate.opsForValue().set("item_"+id,itemModel);
            redisTemplate.expire("item_"+id,10, TimeUnit.MINUTES);
        }
        ...
    ```
    

    Service层,DAO层操作省略,简单的查询操作。
    此时访问/item/get?id=2,查看redis


    未序列化使用

    2. 序列化key和value

    itemModel中有joda.time类型字段,因此采用json序列化和反序列化方式对时间字段进行处理
    
    • RedisConfig.java

      @Component
      @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 3600)
      public class RedisConfig {
      @Bean
      public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
          RedisTemplate redisTemplate = new RedisTemplate();
          redisTemplate.setConnectionFactory(redisConnectionFactory);
      
          //首先解决key序列化方式
          StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
          redisTemplate.setKeySerializer(stringRedisSerializer);
      
          //解决value序列化方式
          Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
      
          ObjectMapper objectMapper = new ObjectMapper();
          SimpleModule simpleModule = new SimpleModule();
          simpleModule.addSerializer(DateTime.class, new JodaDateTimeJsonSerializer());
          simpleModule.addDeserializer(DateTime.class, new JodaDateTimeJsonDeSerializer());
      
          objectMapper.registerModule(simpleModule);
          jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
          redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
          return redisTemplate;
      }
      

    }
    ```

    • JodaDateTimeJsonSerializer.java

    public class JodaDateTimeJsonSerializer extends JsonSerializer<DateTime> {
    
        @Override
        public void serialize(DateTime dateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeString(dateTime.toString("yyyy-MM-dd HH:mm:ss"));
        }
    }
    
    
    • JodaDateTimeJsonDeSerializer.java

    public class JodaDateTimeJsonDeSerializer extends JsonDeserializer<DateTime> {
        @Override
        public DateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            String dateString = jsonParser.readValueAs(String.class);
            DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
            return DateTime.parse(dateString,formatter);
        }
    }
    

    先清理掉redis中的数据(flushall命令),再次访问/item/get?id=2,查看redis


    序列化使用redis

    此时能够看到序列化后的key和value值,但存在一个问题,第一次访问后,数据能保存到redis中,但是再次访问时(访问redis内数据)会报错


    请求redis内数据报错
    查看console显示
    Resolved [java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.miaoshaproject.service.model.ItemModel]
    

    这是因为前面redis保存的value信息只是一个json字符串,没有指定包含的类的信息,因此必须在jackson对应的序列化方式中,没有包含类的信息需要在转化方法中强制指定类的信息。
    因此需要在RedisConfig中加入

    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    

    此时查看redis


    加入类信息

    此时,value中标识了如何解析这些参数的信息。至此,redis的简单应用结束。

    相关文章

      网友评论

          本文标题:多级缓存之一:Redis集中式缓存应用

          本文链接:https://www.haomeiwen.com/subject/egmokctx.html