假设需要给 Mysql 设计一套缓存机制缓存中间件采用 Redis,让查询操作先经过缓存,在缓存没有的情况下再去查表。
Redis 缓存中应该如何存储 Mysql 的数据呢?
如果采用 Redis 的 hash 结构存储 Mysql 的一条数据,将 Mysql 的 DbName-TableName 作为 Redis Hash 的 Key,那么 field 应该使用什么呢? field 使用表的 主键 ,查询语句中带有主键的查询可以查找到这条缓存,如果查询语句中 没有主键 那应该如何处理?或者这种思路是不对的什么成熟的方案可以借鉴吗?
1
yitingbai 2021-08-15 00:36:41 +08:00
Mysql 自身就有缓存, 另外常用的 ORM 框架也带有缓存策略配合 redis 啥的, 自己实现还是很难的, 需要面面俱到, 比如你缓存了一个 sql, 记录变动你要更新缓存. 如果想学习可以去研究 orm 库的源码, 如果只是想用在项目中, 就别重复造轮子了
|
2
sutra 2021-08-15 00:39:47 +08:00
有现成的,比如 spring-data-redis 里的 RedisCache.
|
3
sutra 2021-08-15 00:42:31 +08:00
RedisCache 的默认实现方法是 cacheName::key 作为 key,序列化(可以自定义序列化和反序列化对,比如改为使用 json 格式序列化)后的数据作为 value 。不过需要注意的是,大多实现,都存在双写一致性问题。
|
4
sutra 2021-08-15 00:56:05 +08:00 via iPhone
顺便做个广告吧,刚写完的一个使用 Redis sorted set 来存储的 spring cache 实现,可以避免双写一致性问题。https://oxerr.org/spring-cache-redis-scored/zh/index.html
|
5
sutra 2021-08-15 01:07:12 +08:00
另外,从业务角度来讲,一般缓存的数据,不是直接的数据库查询的结果,而是经过一些计算后的更偏向于业务的结果。
|
6
sutra 2021-08-15 01:09:43 +08:00
关于双写一致性问题,我收藏了几篇文章:
Cache-Aside pattern https://docs.microsoft.com/en-us/azure/architecture/patterns/cache-aside 分布式之数据库和缓存双写一致性方案解析 https://www.cnblogs.com/rjzheng/p/9041659.html Consistency between Redis Cache and SQL Database https://yunpengn.github.io/blog/2019/05/04/consistent-redis-sql/ |
7
815979670 2021-08-15 02:35:52 +08:00
看具体场景把,我们这里有一个缓存思路就是
1 把查询的 sql 转换成 md5 然后 当成 key value 是 mysql 的查询结果, 2 如果有 key 就直接返回 value,如果没有就去数据库查询数据 然后缓存进 redis 3 最后给缓存的数据设置一个过期时间 我们当时给的是 5 分钟 |
8
levelworm 2021-08-15 02:52:14 +08:00 via Android
直接把常用的查询缓存在 redis 内部,保存比如三十天的量,如何?我觉得还是看什么用的最多吧,比如说查询 dau 用的最多,就直接把两个月的 dau 扔进去,每天更新一次就行了。
|
9
vindurriel 2021-08-15 10:38:34 +08:00 via iPhone
我觉得中间件不适合做这个 大部分读写场景不需要 少部分需要的差异又很多 key 格式 空值行为 过期时间都是变量 省不了多少事
|
12
bushenx OP |
13
WIN2333 2021-08-15 11:49:32 +08:00
mysql 有自己的缓存,orm 也有,大部分情况下内存缓存就够了,具体问题具体分析,你这个太广了不适合都这么干,最后瓶颈会落在网络交互,以及 redis 的性能尤其是 redis 还是单线程处理的,缓存是应该是多级设计的
|
15
cyrivlclth 2021-08-16 10:29:33 +08:00
@yitingbai mysql8.0 还有缓存吗?
|