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

缓存雪崩

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

形成原因:

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

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

缓存雪崩的避免方案

缓存过期时间设置随机化

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

缓存雪崩的解决方案

1. 限流降级

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

2. 缓存预热

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

缓存穿透

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

形成原因:

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

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

缓存穿透的解决方案

1. 使用布隆过滤器

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

2. 缓存空对象

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

缓存击穿

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

形成原因:

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

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

缓存击穿的解决方案

1、缓存热点数据

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

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

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

相关推荐
莫叫石榴姐1 小时前
一份热乎的阿里25届数据分析面试题
数据库·数据仓库·sql·算法·数据挖掘·数据分析
cong*1 小时前
数据库提权【笔记总结】
数据库·笔记·adb
gbase_lmax2 小时前
gbase8s数据库常见的索引扫描方式
数据库
阳光九叶草LXGZXJ3 小时前
南大通用数仓-GCDW-学习-03-用户管理
linux·运维·数据库·学习
techdashen3 小时前
清理Go/Rust编译时产生的缓存
缓存·golang·rust
Islucas4 小时前
入门Django
数据库·django·sqlite
jnrjian4 小时前
update 强制 NEST_LOOP NL 的理解,被驱动表 inner table
数据库·sql·oracle
新知图书4 小时前
SQL Server 2022的数据类型
数据库·oracle
脑子不好真君4 小时前
MongoDB的备份和恢复命令
数据库·mongodb