Redis 缓存雪崩、缓存穿透、缓存击穿详解

缓存雪崩

缓存雪崩指的是大量缓存数据在同一时间失效,导致所有请求直接打到数据库或下游系统,造成数据库瞬时压力剧增,甚至可能引发系统崩溃。

形成原因:

  • 缓存数据同时过期:由于缓存过期时间设置不合理,导致大量缓存同时失效,所有请求直接落到数据库。
  • 缓存服务器宕机:缓存服务本身发生故障,无法响应请求,所有请求直接到数据库。

假设你有一个热门商品页面,所有缓存的商品数据过期时间相同,比如都设定为 12 小时。当 12 小时一到,所有缓存失效,用户请求打到数据库,数据库承受巨大压力,甚至可能导致崩溃。

缓存雪崩的避免方案

缓存过期时间设置随机化

为每个缓存的键设置不同的过期时间,避免大批量缓存同时失效。可以在原有过期时间的基础上,添加一个随机值(如 1-5 分钟的随机过期时间)。

缓存雪崩的解决方案

1. 限流降级

在发生缓存雪崩时,使用限流机制,限制进入数据库的请求数量。同时可以启用降级策略,例如返回默认数据或空数据来保证系统的可用性。

2. 缓存预热

在系统启动或缓存即将过期时,提前加载常用的数据到缓存中,避免缓存失效后瞬间打爆数据库。这种方式可以通过定时任务来实现。

缓存穿透

缓存穿透 指的是用户请求的数据根本不在缓存和数据库中,导致每次请求都直接查询数据库。即使我们把不存在的数据存入缓存,依然没有命中缓存,从而让缓存失效。

形成原因:

  • 用户恶意请求一些不存在的数据,缓存中没有,数据库也查不到,每次查询都打到数据库,造成数据库负载过大。

如果用户不断请求数据库中不存在的 id,比如负数 id=-1 或很大范围的 id 值,而系统没有处理此类非法请求,导致这些请求每次都穿过缓存直达数据库。

缓存穿透的解决方案

1. 使用布隆过滤器

布隆过滤器(Bloom Filter)是一种空间高效的概率性数据结构,可以快速判断某个数据是否存在。对于不存在的请求,在查询数据库之前先通过布隆过滤器检查是否有该记录,避免穿透到数据库。

2. 缓存空对象

对于查询结果为 null 的数据,直接缓存一个空值,并设置较短的过期时间(如 5 分钟),避免短时间内重复查询这些不存在的数据。

缓存击穿

缓存击穿 指的是某个热点数据在缓存失效的瞬间,有大量并发请求同时到达这个数据,由于缓存过期,这些请求直接打到数据库,导致数据库负载激增。

形成原因:

  • 某些热门数据(热点 key)过期时间到达,但此时有大量并发请求请求这个数据,由于缓存失效,所有请求都会查询数据库,形成短时间内的高并发。

假设你有一个热门商品 id=100 的缓存,在缓存失效时(比如设定 5 分钟后过期),恰好有成千上万的用户访问这个商品。由于缓存失效,所有请求都会同时打到数据库,造成数据库压力激增。

缓存击穿的解决方案

1、缓存热点数据

对于热点数据,可以设置较长的过期时间,或者让这些数据不过期,定期主动更新缓存,避免过期时产生缓存击穿。

2、使用互斥锁(分布式锁)

在缓存失效的瞬间,为第一个请求的线程加锁,只有获取到锁的线程可以访问数据库并更新缓存,其他线程等待缓存更新后再读取缓存,避免数据库被并发请求打爆。

相关推荐
大数据面试宝典3 分钟前
用AI来写SQL:让ChatGPT成为你的数据库助手
数据库·人工智能·chatgpt
努力的小雨8 分钟前
快速上手 KSQL:轻松与数据库交互的利器
数据库·经验分享
Gentle58610 分钟前
labview中连接sql server数据库查询语句
数据库·labview
Gentle58612 分钟前
labview用sql server数据库存取数据到一个单元格
数据库·labview
Daniel 大东13 分钟前
idea 解决缓存损坏问题
java·缓存·intellij-idea
2401_8576363914 分钟前
共享汽车管理新纪元:SpringBoot框架应用
数据库·spring boot·汽车
菲兹园长15 分钟前
表的设计(MYSQL)
数据库·mysql
Java Fans30 分钟前
MySQL数据库常用命令大全(完整版——表格形式)
数据库·mysql
起飞的风筝42 分钟前
【redis】—— 环境搭建教程
数据库·redis·缓存
白萝卜弟弟1 小时前
【MySQL】MySQL函数之JSON_EXTRACT
数据库·mysql·json