缓存穿透、缓存击穿、缓存雪崩区别

高并发下缓存雪崩
Redis中的数据大面积失效(时间过期)的情景

缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到 DB,DB 瞬时压力过重雪崩。
解决方案:
均匀过期:给热点数据设置不同的过期时间,给每个key的失效时间加一个随机值;
原有的失效时间基础上增加一个随机值,比如 1-5 分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
设置热点数据永不过期:不设置失效时间,有更新的话,需要更新缓存;
服务降级:指服务针对不同的数据采用不同的处理方式:
业务访问的是非核心数据,直接返回预定义信息、空值或者报错;
业务访问核心数据,则允许访问缓存,如果缓存缺失,可以读取数据库。
Redis 缓存实例发生故障宕机的场景

实现服务熔断或者请求限流机制
通过监测Redis以及数据库实例所在服务器负载指标,如果发现Redis服务宕机,导致数据库的负载压力增大,我们可以启动服务熔断机制,暂停对缓存服务的访问。
但是这种方法对业务应用的影响比较大,我们也可以通过限流的方式降低这种影响。
举个例子:比如业务系统正常运行时,请求入口每秒最大允许进入的请求数是1万个,其中9000请求个可以被缓存处理,余下1000个会发送给数据库处理。一旦发生雪崩,数据库每秒处理的请求突然增加到1万个,此时我们就可以启动限流机制。在前端请求入口处,只允许每秒进入1000个请求,其他的直接拒绝掉。这样就可以避免大量并发请求发送给数据库。

事前预防
通过主从节点的方式构建 Redis 缓存高可靠集群。 如果 Redis 缓存的主节点故障宕机了,从节点还可以切换成为主节点,继续提供缓存服务,避免了由于缓存实例宕机而导致的缓存雪崩问题。
高并发下缓存穿透
就是去查询一个一定不存在的数据

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中,将去查询数据库,但是数据库也无此记录,我们没有将这次查询的 null 写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。
在流量大时,可能 DB 就挂掉了,要是有人利用不存在的 key 频繁攻击我们的应用,这就是漏洞。
解决方案:
缓存空结果、并且设置短的过期时间。(null结果进行缓存)
如果有大量的Key穿透,缓存空对象会占用宝贵的内存空间。针对这种情况可以给空对象设置过期时间。
设置过期时间之后,可能会有缓存与数据库不一致的情况(后期可能又有这个条数据了)。
布隆过滤:快速判断数据是否存在,避免从数据库中查询数据是否存在,减轻数据库压力。
接口层增加校验:用户鉴权、参数校验(请求参数是否合法、请求字段是否不存在等等。
高并发下缓存击穿
一个key过期,但是被高访问,连续不断的访问可能会缓存击穿

对于一些设置了过期时间的 key,如果这些 key 可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。
这个时候,需要考虑一个问题:如果这个 key 在大量请求同时进来前正好失效,那么所有对这个 key 的数据查询都落到 db,我们称为缓存击穿。
解决方案:
设置热点数据永不过期:不设置失效时间,有更新的话,需要更新缓存;
加互斥锁:单机可以使用synchronized、lock,分布式可以使用lua脚本或分布式锁Redisson。
zookeeper与etcd,用来做锁都比redis要好很多

posted @ 2024-03-14 18:34  初仰  阅读(18)  评论(0编辑  收藏  举报