Redis缓存穿透

Redis 缓存穿透

1. 缓存穿透

数据中不存在id为0的数据,如果请求查询这条数据,在缓存中查询不到,会将请求转到下层的数据库,这就是缓存穿透。

低频的缓存穿透不可避免。

需要防范高频的缓存穿透。

当大量、并发的缓存穿透行为发生时,数据库往往会因为扛不住而引起项目系统瘫痪。

可能的解决方案

Ⅰ. 缓存空对象

请求到redis,当redis没有命中数据时,请求会达到mysql。如果mysql也不存在该数据,则缓存一个空对象(短期)到redis中。即使空对象设置了时限,但依旧可能影响redis与mysql数据不一致,因为在时限内,数据库中此对象可能已生成数据,但redis位及时更新。

这样做可以一定程度上减少缓存穿透行为,但当发生大量的空对象请求,会导致大量的内存占用,redis有LRULFU的内存淘汰策略,可能会将有价值的缓存数据淘汰掉,真正的用户请求过来将会直接访问到数据库。

Ⅱ. 布隆过滤器(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 是可用的。

posted @   ヾ(o◕∀◕)ノヾ  阅读(11)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示