redis缓存雪崩、穿透、击穿概念及解决办法

redis缓存示意图:

redis缓存示意图

缓存雪崩

  • 描述

对于系统A,假设每天高峰期每秒5000个请求,本来缓存在高峰期可以扛住每秒4000个请求,但是当缓存服务器重启或者大量缓存集中在某一个时间段失效,此时1秒5000个请求全部落数据库,数据库必然扛不住,它会报一下警,然后就挂了。此时,如果没有采用什么特别的方案来处理这个故障,DBA很着急,重启数据库,但是数据库立马又被新的流量给打死了,这就是缓存雪崩。

缓存雪崩示意图

  • 解决方案

事前:redis 高可用,主从+哨兵,redis cluster,避免全盘崩溃。
事中:本地 ehcache 缓存 + hystrix 限流&降级,避免 MySQL 被打死。
事后:redis 持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

缓存穿透

  • 描述

对于系统A,假设一秒5000个请求,结果其中4000个请求是黑客发出的恶意攻击。黑客发出的那4000个攻击,缓存中查不到,每次你去数据库里查,也查不到。例如,数据库id是从1开始的,结果黑客发过来的请求id全部都是负数。这样的话,缓存中不会有,请求每次都“视缓存于无物”,直接查询数据库。这种恶意攻击场景的缓存穿透就会直接把数据库给打死。

缓存穿透示意图

  • 解决方案

每次系统 A 从数据库中只要没查到,就写一个空值到缓存里去,比如 set -999 UNKNOWN。然后设置一个过期时间,这样的话,下次有相同的 key 来访问的时候,在缓存失效之前,都可以直接从缓存中取数据。

缓存击穿

  • 描述

某个key非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个key在失效的瞬间,大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞。

缓存击穿示意图

  • 解决方案

可以将热点数据设置为永远不过期,或者基于 redis or zookeeper 实现互斥锁,等待第一个请求构建完缓存之后,再释放锁,进而其它请求才能通过该 key 访问数据。

-------------本文结束感谢您的阅读-------------