关联表查询结果的 Redis 缓存如何设计

362 天前
 3630cn2023
表 T1(id, project_id, score), project 表
T2(id, type),两个表关联查询的接口 A(userId),B(projectId),如果用 userId ,projectId 作为两个接口的 Redis 缓存 key ,那么接口 C 用通过表 1 的 id 更新数据的时候,A ,B 接口的 Redis 缓存如何更新?
2302 次点击
所在节点    Redis
9 条回复
matrix1010
362 天前
这类问题没有完美解决方法,想尽可能自动处理的话可以参考 rails 的 Russian doll caching 。另外推荐看看这篇文章 https://blog.the-pans.com/when-and-how-to-invalidate-cache/
bubble21
362 天前
业务层使用 Spring-Cache 呢 @Cacheable,@CacheEvict ?
InkAndBanner
361 天前
首先问题描述的挺不清晰的
1. userId 是哪个表的 id ? T1 吗?
2. 那“如果用 userId ,projectId 作为两个接口的 Redis 缓存 key” 意思是分别做 AB 两个接口的返回值缓存?还是 UserId+projectId 做 key ,score 做 value ?
如果缓存的是连表查询的结果,并且假设你问的是更新方案的思路 那么俺觉得任意一表有写操作的时候,就应该把缓存失效掉。如果并发不高 直接更新缓存也是可以的。2 楼说的是具体的实现方案了。
3630cn2023
361 天前
@matrix1010
感谢分享这篇好文章,看了大致思路是建一个 key 的关联表( A ,B ,C 接口缓存的 key ),C 接口更新数据的时候,通过这个 key 关联表查处 A ,B 接口哪些 key 要更新
这样做成本太大了,就跟你说的一样,这类问题没有完美解决方法,这个文章的思路并不通用,
3630cn2023
361 天前
@bubble21
@3630cn2023
A ,B 接口的 key 如何设计,C 接口更新的时候如何更新 A ,B 接口的缓存?
其实问题就是一份数据被缓存了两份,如何保证数据一致性
3630cn2023
361 天前
@matrix1010 应该说这个文章的实现不通用,思路是可以通用的
whoami9426
361 天前
对于读多写少的场景可以这样设计:
0. 缓存 key 上添加 sql 的标识以及参数: com.xx.xxmaaper.selectX1: userId: projectId
1. 获取 sql 中关联的表名,设计存储这样的 json, json 中的 key 为表名,value 为 缓存过的相关的 sql 标识,设个过期时间取个名放到 redis 中
```json
{
"T1":["com.xx.xxmaaper.selectX1"] ,
"T2": ["com.xx.xxmaaper.selectX1"]
}
```
2. 写一个拦截器,拦截修改更新的 sql ,获取上一步中的 json,如果更新的 sql 中所涉及的表存在于这个 json key 中,前缀删除 redis 中这个 key 的 values 也就是缓存过的 sql 结果,同时更新这个 json.
totoro52
361 天前
我觉得这是缓存颗粒度大小的问题,根据场景来决定缓存的颗粒度
sampeng
361 天前
这就是一个缓存设计问题。可大可小。引入缓存就要仔细解决缓存不一致问题。连表查这种缓存不一致是最熬人的。没什么特别通用的办法。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1003357

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX