Redis_缓存穿透、击穿、雪崩

时间:2022-11-11 11:55:05

查询步骤图解

Redis_缓存穿透、击穿、雪崩

1.缓存穿透

什么是缓存穿透: 

        查询请求一直向数据库查询,导致数据库压力过大,甚至奔溃

        本质原因:查询的数据既不在缓存中,也不在数据库中

        此时会出现:程序向缓存查询,发现无数据,遂向数据库查询,发现任然无数据,此时程序无法将数据写入缓存,导致后续的同类型的查询请求,会一直访问数据库;若请求数量极大,则会极大地增加数据库的压力,甚至让数据库奔溃

        导致缓存穿透的可能原因:

                1.业务层操作不当:将缓存与数据库的该数据都删除了

                2.存在恶意攻击者:专门请求查询不存在的数据

解决方案:

1.添加校验参数

        校验前段传递的参数,若不合理则直接返回,不予查询

2.设置空值缓存

        将空数据的 key 设置为 null 存入缓存,如此一来查询该 key 将直接返回 null ,无需向数据库查询(该方法会产生数据的一致性问题,即缓存中的空值缓存尚未过期,但数据库中已有数据,此时查询返回的结果为空值;注:千万记得设置过期时间)

3.添加布隆过滤器(Bloom Filter)

        Bloom Filter是由Howard Bloom在1970年提出的二进制向量数据结构,其具有空间和时间效率,被用来检测一个元素是否是集合的成员,检测结果分为在集合内(可能误判)与不在集合内(绝对准确)两种情况

2.缓存击穿

什么是缓存击穿:

        大量查询请求并发查询同一个热点 key ,而该 key 又正好失效,此时大量查询请求将涌向数据库,就像一面完整的墙上被凿穿了一个点,将导致数据库压力骤增,甚至奔溃

解决方案

1.不过期

        设置热点数据永不过期,通过定时任务刷新数据(注意使用场景)

2.分布式锁

        对热点数据加分布式锁;当热点 key 过期后,第一个查询请求向数据库查询时,其余查询请求会被阻塞,直到锁被释放;后续进入的请求会直接从缓存中读取数据,因为第一个查询请求完成后,数据已被写入缓存

        但是该方法会阻塞其他线程,会造成程序的吞吐量下降

3.缓存雪崩

什么是缓存雪崩

        缓存数据大量失效缓存服务宕机,导致大量查询请求直接向数据库查询,导致数据库压力骤增,甚至奔溃;若无特殊处理办法就重启数据库,通常会出现:数据库奔溃---数据库重启---数据库奔溃---数据库重启······ 的循环

解决办法

1.Redis集群(Redis Cluster)

        通过部署Redis集群与哨兵集群,尽量避免因Redis服务器宕机而导致雪崩

如果缓存雪崩造成的原因是因为缓存服务宕机造成的,可以将redis采用集群部署,可以使用 主从+哨兵 ,Redis Cluster 来避免 Redis 全盘崩溃的情况。若缓存雪崩是因为大量缓存因为失效时间而造成的,我们在批量往redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效,或者设置热点数据永远不过期,有更新操作就更新缓存就可以了。

2.设置数据过期时间随机

        避免因一时间内大量数据过期而导致雪崩

3.设置数据永不过期

        理由同上,通过定时任务更新数据

已发生雪崩的处理方案

        若之前未考虑缓存雪崩的情况,但实际环境中确实发生了雪崩,可以通过以下方式补救:

1.ehcache本地缓存

2.Hystrix限流/降级