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

接上一篇分布式会话实现(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的简单应用结束。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • NOSQL类型简介键值对:会使用到一个哈希表,表中有一个特定的键和一个指针指向特定的数据,如redis,volde...
    MicoCube阅读 3,958评论 2 27
  • 五种数据结构简介 Redis是使用C编写的,内部实现了一个struct结构体redisObject对象,通过结构体...
    彦帧阅读 6,931评论 0 14
  • 我眼前是一片空白, 迷茫。 我看不见前方, 那个, 是否是星星? 我有一座灯塔, 但我的眼里只有空白。 恐惧, 恐...
    风善阳阅读 357评论 5 5
  • 在近期开发的项目中,分别使用到了HTML5的 sessionStorage 和 localStorage,特此做下...
    前端小白简简阅读 827评论 0 0
  • 懒惰,颓废,狂躁,懊恼,迷茫…我的情绪变化没有人在意,包括我自己。 人生在世,活着的定义到底是什么...
    赤座灯里酱阅读 277评论 2 11