0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

缓存被穿透了如何解决

马哥Linux运维 来源:马哥Linux运维 2023-05-23 09:54 次阅读

首先来了解几个概念:

缓存穿透:大量请求根本不存在的key

缓存雪崩:redis中大量key集体过期

缓存击穿:redis中一个热点key过期(大量用户访问该热点key,但是热点key过期)

穿透解决方案

对空值进行缓存

设置白名单

使用布隆过滤器

网警

雪崩解决方案

进行预先的热门词汇的设置,进行key时长的调整

实时调整,监控哪些数据是热门数据,实时的调整key的过期时长

使用锁机制

击穿解决方案

进行预先的热门词汇的设置,进行key时长的调整

实时调整,监控哪些数据是热门数据,实时的调整key的过期时长

使用锁机制

三者出现的根本原因在于Redis命中率下降,请求直接打在DB上。

正常情况下,大量的资源请求都会被redis响应,在redis得不到响应的小部分请求才会去请求DB,这样DB的压力是非常小的,是可以正常工作的(如下图)

32969420-f8f4-11ed-90ce-dac502259ad0.png

如果大量的请求在redis上得不到响应,那么就会导致这些请求会直接去访问DB,导致DB的压力瞬间变大而卡死或者宕机。

大量的高并发的请求打在redis上

这些请求发现redis上并没有需要请求的资源,redis命中率降低

因此这些大量的高并发请求转向DB(数据库服务器)请求对应的资源

DB压力瞬间增大,直接将DB打垮,进而引发一系列“灾害”

如下图所示

32b3e2d2-f8f4-11ed-90ce-dac502259ad0.png

那么为什么redis会没有需要访问的数据呢?通过分析大致可以总结为三种情况,也就对应着redis的雪崩、穿透和击穿

32caafa8-f8f4-11ed-90ce-dac502259ad0.png

情景分析

缓存穿透

缓存穿透产生的原因:请求根本不存在的资源(DB本身就不存在,Redis更是不存在)

举例(情景在线):客户端发送大量的不可响应的请求

当大量的客户端发出类似于:http://localhost:8080/user/19833?id=-3872 的请求,就可能导致出现缓存穿透的情况。因为数据库DB中本身就没有id=-3872的用户的数据,所以Redis也没有对应的数据,那么这些请求在redis就得不到响应,就会直接打在DB上,导致DB压力过大而卡死情景在线或宕机。

缓存穿透很有可能是黑客攻击所为,黑客通过发送大量的高并发的无法响应的请求给服务器,由于请求的资源根本就不存在,DB就很容易被打垮了。

解决方案

对空值进行缓存:

类似于上面的例子,虽然数据库中没有id=-3872的用户的数据,但是在redis中对他进行缓存(key=-3872,value=null),这样当请求到达redis的时候就会直接返回一个null的值给客户端,避免了大量无法访问的数据直接打在DB上

实时监控:

对redis进行实时监控,当发现redis中的命中率下降的时候进行原因的排查,配合运维人员对访问对象和访问数据进行分析查询,从而进行黑名单的设置限制服务(拒绝黑客攻击)

使用布隆过滤器

使用BitMap作为布隆过滤器,将目前所有可以访问到的资源通过简单的映射关系放入到布隆过滤器中(哈希计算),当一个请求来临的时候先进行布隆过滤器的判断,如果有那么才进行放行,否则就直接拦截

接口校验

类似于用户权限的拦截,对于id=-3872这些无效访问就直接拦截,不允许这些请求到达Redis、DB上。

注意事项:

使用空值作为缓存的时候,key设置的过期时间不能太长,防止占用太多redis资源

使用空值作为缓存只能防止黑客重复使用相同的id暴力攻击,但是如果黑客使用动态的无效id攻击就没有效果(需要配合网警)

使用布隆过滤器也是有哈希冲突的可能

缓存雪崩

缓存雪崩产生的原因:redis中大量的key集体过期

举例:

当redis中的大量key集体过期,可以理解为redis中的大部分数据都被清空了(失效了),那么这时候如果有大量并发的请求来到,那么redis就无法进行有效的响应(命中率急剧下降),请求就都打到DB上了,到时DB直接崩溃。

解决方案:

将失效时间分散开

通过使用自动生成随机数使得key的过期时间是随机的,防止集体过期

使用多级架构

使用nginx缓存+redis缓存+其他缓存,不同层使用不同的缓存,可靠性更强

设置缓存标记

记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去跟新实际的key

使用锁或者队列的方式

如果查不到就加上排它锁,其他请求只能进行等待

缓存击穿

产生缓存雪崩的原因:redis中的某个热点key过期,但是此时有大量的用户访问该过期key

举例:

类似于“某男明星塌房事件”上了热搜,这时候大量的“粉丝”都在访问该热点事件,但是可能优于某种原因,redis的这个热点key过期了,那么这时候大量高并发对于该key的请求就得不到redis的响应,那么就会将请求直接打在DB服务器上,导致整个DB瘫痪。

解决方案:

提前对热点数据进行设置

类似于新闻、某博等软件都需要对热点数据进行预先设置在redis中

监控数据,适时调整

监控哪些数据是热门数据,实时的调整key的过期时长

使用锁机制

最后的防线,当热点key过期,那么就使用锁机制防止大量的请求直接打在DB

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 缓存
    +关注

    关注

    1

    文章

    239

    浏览量

    26665
  • 过滤器
    +关注

    关注

    1

    文章

    427

    浏览量

    19590
  • key
    key
    +关注

    关注

    0

    文章

    49

    浏览量

    12825

原文标题:缓存被穿透了怎么办?

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    何解决数据库与缓存一致性

    缓存一致性 每次逢年过节的时候抢票非常艰难,放票的时候那么多人同时去抢票,如果所有人查询、购票等都去访问数据库,那数据库的压力得有多大,这时候很多都会引入缓存, 把车票信息放入缓存,这样可以减少
    的头像 发表于 09-25 15:25 1097次阅读
    如<b class='flag-5'>何解</b>决数据库与<b class='flag-5'>缓存</b>一致性

    何解决蓝牙协议栈锁问题?

    何解决蓝牙协议栈锁问题
    发表于 03-21 08:21

    使用altium designer时候出现了如下错误

    使用altium designer时候出现了如下错误,请问应该如何解决??跪谢!
    发表于 01-26 15:36

    搭建自己的IOT平台---内网穿透

    IOT平台的外网访问。在虚拟机完成IOT平台搭建之后,接下来就是内网穿透了,其实很简单·,只需在花生壳官网注册一个账号,每个账号都会有两个免费的内网穿透的域名供你使用。官网网址 https
    发表于 12-09 23:14

    汽车电池没电了如何解决?教你“借电”技巧

    汽车电池没电了如何解决?教你“借电”技巧 要发动汽车,却发现电池没电了,想必许多人都遇到过这种情况。所以,如何正确“借电”也是开车的一门
    发表于 11-06 08:44 7715次阅读

    iphone密码多次输入错误锁如何解?

    iphone密码多次输入错误锁如何解? iPhone允许您设置一个密码,在开机或按下唤醒按钮时可以输入此密码。这在 iPhone用户指南和功能
    发表于 02-02 09:45 3.3w次阅读

    何解决模拟混合信号设计的挑战

    这种按需网络研讨会演示了如何解决模拟混合信号设计挑战增加可靠性和速度与AMS垫专业产品开发。
    的头像 发表于 10-18 07:08 3522次阅读

    缓存雪崩/穿透/击穿的解决方案

    缓存是我们项目应用肯定会使用,是我们数据库的守护神,能够保证数据库的稳定,能够提高整个系统的性能。一般我们采用市面上的redis、memcahce方案;redis已经非常强大了,每秒支持几万的连接时不成问题。
    发表于 01-26 09:44 1311次阅读
    <b class='flag-5'>缓存</b>雪崩/<b class='flag-5'>穿透</b>/击穿的解决方案

    如何设计一个缓存系统?

    设计一个缓存系统,不得不要考虑的问题就是:缓存穿透缓存击穿与失效时的雪崩效应。 缓存穿透
    的头像 发表于 02-08 11:40 2913次阅读

    如何在SpringBoot中解决Redis的缓存穿透等问题

    今天给大家介绍一下如何在SpringBoot中解决Redis的缓存穿透缓存击穿、缓存雪崩的问题。
    的头像 发表于 04-28 11:35 724次阅读

    基于循环队列的FIFO缓存实现

    FIFO缓存是介于两个子系统之间的弹性存储器,其概念图如图1所示。它有两个控制信号,wr和rd,用于读操作和写操作。当wr插入时,输入的数据写入缓存,此时读操作被忽视。FIFO
    的头像 发表于 09-11 10:12 797次阅读
    基于循环队列的FIFO<b class='flag-5'>缓存</b>实现

    为什么GPU获得了如此多的缓存

    不久之前,如果您想要一个内置大量缓存的处理器,那么 CPU 是显而易见的选择。现在,即使是预算级 GPU 也比几年前的高端 CPU 配备了更多的内存。
    的头像 发表于 10-07 17:37 1809次阅读
    为什么GPU获得<b class='flag-5'>了如</b>此多的<b class='flag-5'>缓存</b>?

    如何使用缓存

    缓存技术认为是减轻服务器负载、降低网络拥塞、增强Web可扩展性的有效途径之一,其基本思想是利用客户访问的时间局部性(Temproral Locality)原理, 将客户访问过的内容在Cache中
    的头像 发表于 10-08 14:07 615次阅读

    Redis缓存预热+缓存雪崩+缓存击穿+缓存穿透要点简析

    缓存预热就是系统上线后,提前将相关的缓存数据直接加载到缓存系统。
    的头像 发表于 12-25 09:41 892次阅读
    Redis<b class='flag-5'>缓存</b>预热+<b class='flag-5'>缓存</b>雪崩+<b class='flag-5'>缓存</b>击穿+<b class='flag-5'>缓存</b><b class='flag-5'>穿透</b>要点简析

    HTTP缓存头的使用 本地缓存与远程缓存的区别

    :资源的特定版本标识,用于验证资源是否修改。 Last-Modified :资源最后修改时间,用于验证资源是否修改。 Vary :告诉缓存服务
    的头像 发表于 12-18 09:41 51次阅读