美文网首页
“Redis缓存穿透”规避方案

“Redis缓存穿透”规避方案

作者: 程序员网址导航 | 来源:发表于2019-08-23 18:53 被阅读0次

    Redis被应用于缓存


    Redis作为当前一个非常热门的NoSQL,也被频繁应用在多个场景下,比如被作为缓存来减少DB的负载;分布式环境下分布式锁的应用;全局唯一ID实现方案之一;还有人利用Redis的List数据类型实现消息队列……

    下图是一个Redis被用作缓存,以减小DB负载,通过对内存的高效利用来提升系统的并发度的一个简单的场景。

    过程简述:系统接受到数据查询请求后,先去查询Redis,如果Redis命中了,则直接将Redis的查询结果返回;如果Redis没有命中,紧接着去查询DB,最后将DB查询结构返回;

    image.png

    这个设计直接、简单,并且多数情况下直接这样使用也不会有问题的。

    缓存穿透的原理

    如上图所示,缓存就像是数据库的一道防火墙,将请求频繁的数据放入到缓存,可以减轻数据库的访问压力。但是如果有人想要恶意攻击,其实是很容易穿透现有的缓存。比如我们的redis key的生产规则是这样子的,客户code+“_”+业务编号(其中业务编号可能是直接利用UUID生成的一个32位长度字符串)。

    image.png

    一般情况下我们API调用都会在网关层做客户code校验,判断当前code是否合法,或者会有流量校验等拦截逻辑。但是如果别人知道了我们的code,使用一个简单的缓存key来一直查我们的接口("code_111"),这种情况下因为code已经通过了我们的客户code校验,所以请求会直接查缓存,但是这个查询的key一定是不在缓存中的,所以每次都次查询DB,相当于多有的请求都会打到DB上。缓存形同虚设,很容易把库搞挂,这个问题被称为”缓存穿透“

    image.png

    可能导致缓存穿透的几个原因


    1.就像上面说了,攻击者猜中你的缓存key生成规则,或者就拿一个不合法的key来一直查你的接口;
    2.第一次数据访问,缓存中没有数据,大并发下所有的请求都会打的库上;
    3.数据库的数据也是空的,即使访问了数据库,也是没有数据,那缓存中自然也没有数据;

    解决缓存穿透的方案


    其实最简单的便是针对可能导致缓存穿透的原因逐一规避:

    image.png

    第一步:在服务启动之前,先将我们可以预测到的可能会被频繁访问的热点数据导入到缓存;

    第二步:在命中缓存之前,可以根据我们缓存中key的生成规则做一次简单的规则校验。比如我们的key应该是 code_32为长度的字符串,但是当前的请求key的code_不满足32位长度字符串格式可以直接拒绝掉。

    第三步:Synchronized双重检测机制,这时我们需要使用同步机制,在同步代码之前先查一次缓存,看key是否存在,如果不存在在同步代码块里再次查询缓存看是否有key。这样”双重检查的目的“,还是避免并发场景下导致没有意义的数据库查询。

    第四步:不管数据库中是否有数据,都在缓存中保存对应的key,值为空就行。–这样是为了避免数据库中没有这个数据,导致的平凡穿透缓存对数据库进行访问。

    第五步:第4步中的空值如果太多,也会导致内存耗尽。导致不必要的内存消耗。这样就要定期的清理空值的key。避免内存被恶意占满。导致正常的功能不能缓存数据。

    个人网站:relaxheart网

    相关文章

      网友评论

          本文标题:“Redis缓存穿透”规避方案

          本文链接:https://www.haomeiwen.com/subject/bpmzsctx.html