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

2019-07-15  本文已影响0人  YoSaukit

接上一篇分布式会话实现(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序列化和反序列化方式对时间字段进行处理

}
```

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

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的简单应用结束。

上一篇下一篇

猜你喜欢

热点阅读