DCS Redis 缓存实战:穿透、击穿、雪崩的三道防线

举报
yd_270427807 发表于 2026/11/09 09:44:55 2026/11/09
【摘要】 一、缓存出问题,往往不是 Redis 慢了,而是防线没建很多团队用缓存的方式是这样的:业务先查 Redis,查不到再查数据库,查到就回填。平时跑得好好的,某天流量一上来,数据库突然被打满,服务跟着超时——回头一看,Redis 本身没慢,问题出在大量请求绕过了缓存,直接冲到了数据库。缓存的三大经典故障——穿透、击穿、雪崩——名字很像,但成因和解法完全不同。穿透是查了不存在的数据,击穿是热点 K...

一、缓存出问题,往往不是 Redis 慢了,而是防线没建

很多团队用缓存的方式是这样的:业务先查 Redis,查不到再查数据库,查到就回填。平时跑得好好的,某天流量一上来,数据库突然被打满,服务跟着超时——回头一看,Redis 本身没慢,问题出在大量请求绕过了缓存,直接冲到了数据库。

缓存的三大经典故障——穿透、击穿、雪崩——名字很像,但成因和解法完全不同。穿透是查了不存在的数据,击穿是热点 Key 刚好过期,雪崩是一大批 Key 同时过期。下面按这三道防线展开。

二、第一道防线:防穿透——别让不存在的数据反复打数据库

缓存穿透是指查询一个数据库里根本不存在的数据:Redis 里没有,数据库里也没有,每次请求都要穿透缓存去查数据库。单个请求代价不大,但攻击者或异常流量用大量不存在的 ID 轮询时,数据库很快就被拖垮。

  • 空值也要缓存:查不到时,把一个空值写进 Redis,并设一个较短的过期时间(比如 60 秒)。下次同样的请求直接命中空值,不再打数据库。注意空值的过期时间要比正常值短得多,避免正常数据写入后还长时间返回空。
  • 布隆过滤器前置拦截:在 Redis 前面加一层布隆过滤器,先判断这个 Key 有没有可能存在。不存在就直接返回,不再往下查。布隆过滤器有少量误判(把不存在的判成存在),但不会把存在的判成不存在,所以适合做前置拦截。
  • 参数校验先行:ID 格式明显非法的请求(比如负数、超长字符串),在网关或业务层直接拒绝,不要一路查到数据库。

关键动作:空值缓存是底线,布隆过滤器是加固。只做参数校验挡不住合法格式的恶意查询,空值缓存加布隆过滤器,才能把穿透的量级压下来。

三、第二道防线:防击穿——热点 Key 过期那一刻,别让所有请求一起冲数据库

缓存击穿是指某个热点 Key 刚好过期,而这时恰好有大量并发请求都在查它:Redis 里没了,所有请求同时回源数据库,瞬间把数据库打满。热点 Key 平时扛住了 99% 的流量,过期那一秒就成了单点。

  • 热点 Key 永不过期,改用逻辑过期:把过期时间写在缓存值内部,而不是依赖 Redis 的 TTL。读到逻辑过期的数据时,先返回旧值,再由一个线程异步刷新缓存,其他请求继续用旧值,不会同时冲数据库。
  • 互斥锁只放一个请求回源:第一个发现缓存缺失的请求先拿锁去查数据库、回填缓存,其他请求短暂等待后重试读缓存。锁要有超时和释放机制,避免拿锁的请求挂了之后所有人一直等。
  • 热点 Key 提前预热:上线前、活动开始前,主动把热点数据刷进缓存;对已知会过期的热点 Key,在过期前主动刷新,不要等它自然过期。

关键动作:击穿防的是“同一时刻的并发回源”。逻辑过期适合读多写少的热点数据,互斥锁适合更新不频繁、能接受短暂等待的场景,两者可以结合用。

四、第三道防线:防雪崩——别让一大批 Key 在同一时刻集体过期

缓存雪崩是指大量 Key 在同一时间过期,或者 Redis 本身宕机:平时由缓存扛住的流量,在一瞬间全部落到数据库上。雪崩和击穿的区别在于规模——击穿是一个热点 Key,雪崩是一大批 Key。

  • 过期时间加随机抖动:不要给一批 Key 设完全相同的 TTL。在基础过期时间上加一个随机值(比如 0 到 10 分钟),让它们错峰过期。这是成本最低、最先要做的一件事。
  • 缓存分层、服务降级:关键接口保留本地缓存做第二层,Redis 不可用时先返回本地缓存的旧数据;同时准备降级开关,非核心接口在压力大时直接返回默认值或提示,把数据库资源留给核心接口。
  • Redis 高可用和限流:生产环境用主备或集群模式,避免单点故障;数据库一侧做好连接池上限和慢查询监控,流量真的冲过来时,限流比硬扛更能保住核心服务。

关键动作:雪崩防的是“同一时刻的集体失效”。随机过期时间解决的是“同时过期”,高可用和降级解决的是“Redis 本身不可用”,两者缺一不可。

五、一个可落地的检查清单

  1. 查不到的数据有没有做空值缓存,空值过期时间是不是比正常值短得多?
  2. 热点 Key 有没有用逻辑过期或互斥锁,避免过期瞬间并发回源?
  3. 批量写入的 Key,过期时间有没有加随机抖动,而不是全部相同?
  4. Redis 有没有做主备或集群,单点故障时业务能不能降级?
  5. 数据库连接池、慢查询、缓存命中率有没有监控和告警?
  6. 有没有做过一次缓存失效演练,验证雪崩时降级开关是否真的生效?

一句话总结:缓存的三道防线,防的是三种不同的失效方式。穿透防不存在的数据,击穿防热点 Key 过期那一刻,雪崩防一大批 Key 同时失效——三道防线都建好,缓存才能真正替数据库扛住流量。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。