咨询一个 redis 穿透的问题,看看大佬有什么解决方案没有

2021-03-08 17:41:30 +08:00
 BinYang

背景:在被访问数据库中没有的数据时,此时会访问 db 。线上 90%的数据都是数据库没有的(业务场景限定)。此时为了解决缓存穿透的问题,引入了 redis 设置空值。此时导致的结果是(数据是 n x n )的。导致线上 redis 有 3 亿的空值 key 。

解决思考:如果使用布隆过滤器,受限制于不能删除元素限制。不能使用,有什么更好的解决方案吗?

7203 次点击
所在节点    Java
97 条回复
qwer666df
2021-03-08 17:45:01 +08:00
设置了空值之后, 在加个过期时间?
shoushi
2021-03-08 17:48:31 +08:00
我对这个场景感兴趣
xx6412223
2021-03-08 17:51:28 +08:00
n*n 的 肯定有共同前缀吧,而且大部分都是空。按前缀设置一部分空值。
BinYang
2021-03-08 17:55:09 +08:00
@qwer666df 过期时间已经加了,目前是设置了 3 天的过期事件(正常热点数据也是 3 天)。3 天 redis 的值大概会到达 2 亿左右。redis 内存消耗太快了。
BinYang
2021-03-08 17:56:45 +08:00
@shoushi 场景就是上述的场景。
就是有一个表保存了点对点的关系。但是线上大多数点和点之间是没有关系的。所以 90%会打到数据库(如果 redis 不做缓存穿透的处理)。
为了做缓存穿透的处理,在数据库查到位空时,在 redis 放了一个 key 等于参数,value 为空的值。但是,这部分值太多了。
BinYang
2021-03-08 17:56:57 +08:00
@xx6412223 目前就是设置的空值
leopod1995
2021-03-08 17:58:31 +08:00
反向思维,整个 db 搬到 redis,9:1 的比例的话,大概 3000w 条数据就可以了吧?

查 redis 就是查 Db, 没有就返回 null 。 启动做数据从 db 到 redis 的冷同步。

唯一的问题就是 从 Db 同步更新 redis
BinYang
2021-03-08 18:01:10 +08:00
@leopod1995
这个方案,有考虑过。这么做的话,相当于强依赖 redis (这样子设计是不是有点蛋疼)
相当于 redis == db 了。一切以 redis 为准。db 相当于只是一个数据的存档了。
skymei
2021-03-08 18:02:50 +08:00
反过来呢,只缓存数据库有的数据到 redis,直接查询命中,没命中的数据库肯定也没有,就直接返空
Kinnice
2021-03-08 18:08:21 +08:00
有点意思,要不给 key 设置个 count,count 少于 xxx 的定时删除。反正也属于是非热点数据。
key value
关键词 A {"count":123,"value":""}
helone
2021-03-08 18:08:38 +08:00
我局的 7 楼的方案就很不错啊,Redis 本身就是数据库,只不过因为高性能所以很多人当作缓存用罢了,强依赖 Redis 没什么不妥的,如果你担心缓存穿透问题,你也可以考虑加个自旋锁
jwenjian
2021-03-08 18:19:14 +08:00
bitmap ?
Numbcoder
2021-03-08 18:20:51 +08:00
1.优化 key 的长度,降低内存占用
2. 慢慢缩短过期时间,直到一个 db 能承受的穿透查询量
3. 调整 Redis 的内存淘汰策略
4. 加内存,硬件白菜价(相对人力成本),加个 8G 内存,没多少钱,轻松解决问题
Numbcoder
2021-03-08 18:25:31 +08:00
不太同意 7 楼的方案,理由:
1. 业务变得更复杂,数据一致性很容易出问题
2. 当你的业务数据增长之后,你会为此付出更大的迁移代价
gBurnX
2021-03-08 18:29:29 +08:00
建议楼主说一下具体业务,硬件配置等,说不定大家的建议又会不一样了。
bthulu
2021-03-08 18:43:22 +08:00
redis 设置 30 分钟过期, 前端 nginx 将同一个点的请求尽量路由到同一后台服务器当中, 业务代码再加一层本地内存缓存, 这样大部分请求本地缓存就搞定了, 到达 redis 的就没多少了
luckyrayyy
2021-03-08 18:47:44 +08:00
3 亿的数量级好像不大啊,想起来之前看微博的关注关系、点赞关系存储,直接存缓存就没问题,不过他们专门做了优化。还有另外一个场景,判断一个微博是否被某个人阅读过,这个关系更庞大,文章上说有上千亿的关系对,专门研发了个基于布隆过滤器的系统存储
lucienhsu
2021-03-08 18:51:14 +08:00
建议说明下具体业务场景
BinYang
2021-03-08 19:01:19 +08:00
@Numbcoder 这个目前也是我们在做的。
已经做了,缩短过期事件,以及迁移到单独的 redis db. 同时已经在探索淘汰策略了。目前我们 redis 的大小是 128GB 。单独给这个业务使用。目前每天增长大概在 7GB 左右。目前来说,redis 满了之后。会出现部分打在 db 。
BinYang
2021-03-08 19:04:47 +08:00
@gBurnX 目前配置是 128GB 的 redis,已经使用了 100GB 左右,key 的数量大概是 2 个多亿,不到 3 亿。

redis 失效时间,设置的是 3 天。(当前,预计在下一版本,降低失效时间到 2 天,逐步降低)

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

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

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

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

© 2021 V2EX