关于Redis缓存的一些思考

前言

从一开始写 BBS-lite 的时候我就有打算整合 Redis 作为缓存, 但是在经历过 MyBatis整合Redis --> Spring Boot封装好了的Redis Cache --> 自己写Jedis控制 --> 自定义注解切入Service层进行缓存 等一系列流程后, 我发现缓存并不是这么简单。上述我使用过的方式都有一定的缺陷…

MyBatis二级缓存整合Redis

MyBatis的二级缓存作用域是基于命名空间的,默认一个XML配置文件内都处于同一命名空间,而通过 MyBatis Generator 生成的 XML 文件每一个都对应了一张表。但是头疼的来了, 在二级缓存里每次进行修改/插入/删除都会刷新当前命名空间内的缓存。也就是说:碰见修改密集的部分模块,用了缓存基本跟没用一样…当然也可能是我才疏血浅不知道更好的方案,不过我在官方文档和Google也没找出合理的解决方案。

使用Spring Boot的组件 spring-boot-starter-redis-cache

用起来能满足基本的缓存需求, 但是由于是通过注册 CacheManager Bean 实现的,所以一些Redis的特性并未体现出来。 即便是通过注册相关配置Bean 能调整的东西也有限。 一些缓存问题也不能很好的处理,如: 缓存雪崩(因为不支持随机TTL)、自增/自减(计数应该是比较频繁的场景了)。

自己写Jedis控制

这个没什么好说的,单纯因为我有代码洁癖…不想在Service里来回调用Jedis引入一大堆重复代码…毕竟基本上每段Service层的代码里都有Jedis相关代码来回穿梭还是很烦的…就跟每个类都定义一个LogFactory的成员变量一样. @Slf4jLog4j什么的它不香嘛?

你把问题抛给我,我先看看我这有没有,没有我去仓库里拿出来给你同时我再记一下答案,这样下次问同样的问题我就不用再跑到仓库里去找了。 抽象一下,就会发现跟AOP很想呐~

一些思考

暂时想不到比较好的解决方案, Google到的也只是Redis Cache的一些基本运用, 达不到我想要的效果。我想写一个比较好用的 Redis 缓存。起码能达到以下效果:

    1. 开箱即用: 通过AOP和自定义注解切入到一些层进行缓存操作。就这块而言很喜欢Spring Boot注解,在简化配置的同时侵入性也很低
    1. 可扩展: 能够被很方便的二次开发, 可以通过自定义配置信息来加入一些自定义操作(比如说某些模块未实现的功能)
    1. 自定义: 可以通过组合注解在原模块的基础注解上进行封装
    1. 能够支持 inc(以及对 zset、 list、 set等数据结构的支持)
    1. 支持随机TTL

然后,注解里应该有以下字段(仅供参考):

  • key/keyGenerator(支持自定义key)
  • ttl(时间)
  • timeType(时间单位,目前我定义了秒/分/时/天)
  • randomTtl(boolean,是否开启随机ttl.p.s:此处开启后应该在ttl一段范围内随机浮动,不用太多,个人觉得±2即可)
  • strategy(缓存过期策略)
  • cacheType(里面应该有四种,默认的新增,inc,delete和flush,当然也可以拆分成四个注解)

不过我现在只在BBS-lite中实现上述 1、4中对inc的支持和 5。

想的时候很简单, 真正到写的时候就不一样了。 一开始想把缓存切入到Service - Dao之间(理论上也应该这样),后来发现Dao是通过MBG(MyBatis Generator)自动生成的,如果表结构后续有改动的话(肯定有改动的)都得写一遍…

而放在Controller - Service之间的话由于AOP是基于proxy模式实现的,所以一些数据组装的活放在Service层的话又会失效。比如我要查看一篇文章的话那么对应的应该调用Service层中 incArticleViewgetArticleInfo 以及 getUserInfo 等方法然后将数据组装,但是如果以这种思路就得把组装放在Controller层(前面有提到过AOP基于proxy模式实现,所以不能"我切我自己"),又违背了单一职责原则

后来又想到单独开一个Cache层,在Cache层中再注入Service,和Service实现同一个接口并加上@Primary注解,然后Controller层通过注入接口调用,如果当前接口有实现Cache的话,则默认通过Cache层代理一些操作。但是这样又回到开头的写Jedis手动控制了…

目前来看,最优方案就只有将注解打在Service - Dao之间的

当然如果有更好方案的,欢迎在下方评论给出建议

关注bestsort公众号,不迷路。主要是一些Java技术栈学习过程以及经验分享
关于Redis缓存的一些思考_第1张图片

你可能感兴趣的:(java)