Redis缓存穿透
Redis 缓存穿透
1. 缓存穿透
数据中不存在id为0的数据,如果请求查询这条数据,在缓存中查询不到,会将请求转到下层的数据库,这就是缓存穿透。
低频的缓存穿透不可避免。
需要防范高频的缓存穿透。
当大量、并发的缓存穿透行为发生时,数据库往往会因为扛不住而引起项目系统瘫痪。
可能的解决方案
Ⅰ. 缓存空对象
请求到redis,当redis没有命中数据时,请求会达到mysql。如果mysql也不存在该数据,则缓存一个空对象(短期)到redis中。即使空对象设置了时限,但依旧可能影响redis与mysql数据不一致,因为在时限内,数据库中此对象可能已生成数据,但redis位及时更新。
这样做可以一定程度上减少缓存穿透行为,但当发生大量的空对象请求,会导致大量的内存占用,redis有LRU
或LFU
的内存淘汰策略,可能会将有价值的缓存数据淘汰掉,真正的用户请求过来将会直接访问到数据库。
Ⅱ. 布隆过滤器(Bloom Filter)
将数据库中存在的id提前存放在一个数组
,后续现在这个数组中查询id是否存在,如果存在则继续下发请求,否则直接返回。
Bloom Filter 适用于次解决方案,以避免当id数据量过大时,数组也会很大,进而导致查询效率大打折扣。
Bloom Filter 是一个占用空间很小、效率很高的随机数据结构,由一个 bit 数组和一组 Hash 算法构成。
Bloom Filter 存在哈希碰撞问题,存在错误的可能性:
- Bloom Filter 说这条数据存在,这条数据不一定存在;
- Bloom Filter 说这条数据不存在,这条数据一定不存在。
2. 缓存击穿
缓存击穿
是缓存穿透的一种特殊表现。
请求量大、请求频率高的key过期,导致大量请求同一时间打到数据库,数据库扛不住,最后系统瘫痪。
此类情况在大多数公司不易发生,因为较难达到这样的一个量级。
可能的解决方案
Ⅰ. 热点数据不过期
热门数据的key设置不过期,这是最简单的方式。
需要考虑:
- 数据是否会变化。
- 数据库与redis的数据一致性如何处理,例如监控数据库的数据变化,同步更新redis中的数据。
Ⅱ. 分布式锁
当key过期时,只运行一个请求发送到数据库,然后将新数据缓存到redis,后续请求继续在redis中处理。
分布式锁的实现:
- zookeeper
- redis
3. 缓存雪崩
缓存雪崩
是缓存穿透的一种特殊表现。
大量的key同时失效,或者redis服务宕机。
可能的解决方案
Ⅰ. 数据预热,缓存时间随机
做一个数据库和redis的数据同步服务,项目启动时,将数据库中的数据加载到redis中,并设置随机的失效时间,每隔一个固定的时间执行一次数据同步。
Ⅱ. redis 集群
为了防止 redis 挂掉,使用 redis 集群做高可用。
可以将数据进行分片,将同样的数据分布到多台机器上,当集群中的一台或几台机器宕机,也依然能保障 redis 是可用的。
本文来自博客园,作者:ヾ(o◕∀◕)ノヾ,转载请注明原文链接:https://www.cnblogs.com/Jupiter-blog/p/18751078
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构