面试题之Redis的穿透、击穿和雪崩问题

一、穿透问题

1、什么是缓存穿透?

访问缓存中没有,数据库中也没有的数据,感觉像穿透了缓存层,直达数据库,每次请求都会访问到数据库,当同时存在大量发送这类请求,遭受到恶意攻击,可能直接压垮数据库。

2、如何解决缓存穿透?

2.1、对查询结果为 null 的数据,也在缓存中存储一个空值(如null""),并设置较短的过期时间(如 5 分钟),避免同个无效请求反复穿透。

2.2、使用布隆过滤器

在缓存前加一层布隆过滤器,预先存储所有可能存在的有效 key(如数据库中所有用户 ID)。请求来时先过过滤器,不存在的 key 直接拦截,不进入缓存和数据库。 查询缓存前,先判断当前key在布隆过滤器中是否存在,一定不存在则直接返回,有可能存在则查询缓存

步骤:1、在将数据存入Redis时,会同时存储一个Redis的键到布隆过滤器中,会通过布隆过滤器提供的多个Hash函数对Key进行Hash运算,再对位数组长度进行取余,得到一个下标,将该下标值设置为1

2、在查询时,会先按存储Redis到布隆过滤器中的方法,去判断当前的Key是否在布隆过滤器中,结果有两种: 一定不存在【位数组对应的下标上有一个或多个是0】,直接返回 有可能存在【位数组对应的下标上每个对应值都1】,查Redis

二、击穿问题

1、什么是缓存击穿?

某个 "热点 key" 突然失效(过期或被删除),而此时恰好有大量并发请求访问该 key,瞬间所有请求都穿透到数据库,造成数据库压力骤增。
场景 :比如电商大促时,某个热门商品的缓存突然过期,瞬间 thousands 级请求同时查询该商品,直接冲击数据库。

2、如何解决缓存雪崩?

  • 分布式锁 :当缓存失效时,不是所有请求都去查数据库,而是用分布式锁(如 Redis 的setnx)控制,只让一个请求去数据库查询并更新缓存,其他请求等待重试。

    例:请求发现缓存失效 → 尝试setnx lock:product:100 1 EX 5 → 拿到锁的请求查库更新缓存 → 释放锁 → 其他请求重试时命中缓存。

  • 热点 key 永不过期

    • 从缓存层面:不设置过期时间(但需业务层定期主动更新,避免数据陈旧)。
    • 从逻辑层面:设置过期时间,但另起线程在过期前主动更新缓存(如过期前 10 分钟刷新)。
  • 接口限流或者降级

三、缓存雪崩(Cache Avalanche)

本质大量缓存 key 在同一时间集体失效 (如缓存服务宕机,或大量 key 设置了相同过期时间),导致海量请求瞬间全部打到数据库,数据库无法承受压力而崩溃。场景:比如凌晨 3 点对所有商品缓存设置了 24 小时过期,次日凌晨 3 点所有商品缓存同时失效,恰逢用户高峰期,数据库被瞬间压垮。

解决方案

  • 过期时间随机化 :给不同 key 的过期时间加一个随机值(如EX 3600 + Math.random()*1000),避免大量 key 同时过期。
  • 缓存集群高可用:部署 Redis 集群(主从 + 哨兵或 Redis Cluster),避免单节点宕机导致整个缓存服务不可用。
  • 服务熔断与限流:用 Sentinel、Hystrix 等组件对数据库请求限流,当请求量超过阈值时,直接返回降级结果(如 "系统繁忙"),保护数据库。
  • 多级缓存:增加本地缓存(如 Caffeine),即使分布式缓存失效,本地缓存也能承接部分请求,减少对数据库的冲击。
相关推荐
2401_8370885010 小时前
stringRedisTemplate.opsForHash().entries
java·redis
爱敲键盘的猴子12 小时前
Redis内存回收,缓存问题
redis
顺凡12 小时前
删一个却少俩:Antd Tag 多节点同时消失的原因
前端·javascript·面试
码事漫谈12 小时前
智能体颠覆教育行业调研报告:英语、编程、语文、数学学科应用分析
后端
蓝-萧12 小时前
使用Docker构建Node.js应用的详细指南
java·后端
爬山算法12 小时前
Redis(110)Redis的发布订阅机制如何使用?
前端·redis·bootstrap
码事漫谈13 小时前
《C语言点滴》——笑着入门,扎实成长
后端
Tony Bai13 小时前
【Go模块构建与依赖管理】09 企业级实践:私有仓库与私有 Proxy
开发语言·后端·golang
咖啡教室13 小时前
每日一个计算机小知识:ICMP
后端·网络协议
间彧13 小时前
OpenStack在混合云架构中通常扮演什么角色?
后端