缓存穿透问题与解决方法

一、什么是缓存的穿透问题?

如图,一个正常的请求一般都会经过cache层再到storage层。

而因为在storage中获取不到数据,没有把数据放在cache里,导致了大量请求都达到了storage层,这就是缓存穿透的一个定义。

缓存的一个作用就是保护storage,也就是MySQL之类的数据库,而缓存穿透的话就失去了这一层保护

二、什么原因导致了缓存穿透?

  • 业务代码自身问题:之前我遇到过有人写的代码查出来是有数据的,但是存到cache的时候用了一个空的变量。这种是比较低级的,但是也是有这种情况
  • 恶意攻击、爬虫等等:例如一个GET的接口,如果攻击者一直在参数里面传一些不正常的值,就会导致大量的请求都无法cache到,就必然会导致缓存穿透,数据量足够大的情况下还会导致storage挂掉

三、如何发现缓存穿透?

  • 业务的响应时间:我们可以借助ELK或其他监控系统,对业务的接口进行检测。原本缓存就是响应时间比较快的,如果经常超过阈值就一定会有所体现
  • 业务本身问题
  • 相关指标:总调用数、cache层命中数、storage层命中数

四、如何解决缓存穿透问题?

  • 缓存空对象:如果storage中确实是null的话,我们也可以缓存一个空对象,同时设置一个过期时间,比如说5分钟、8分钟,这个要看具体的使用场景。虽然说storage中确实是null,但是这样可以为我们减缓storage的压力,避免一些缓存穿透的危害。

可能存在的问题:

  1. 需要更多的键:像我们前面提到的恶意攻击,如果每次请求的key都不一样,那就会将这些key都写入cache,虽然只是一个null值,但如果数据量大的话还是会一些影响,所以我们一般都是使用过期时间来降低这样的风险。
  2. cache层和storage层会有“短期”不一致:因为cache层设置了过期时间,如果storage层是某一个接口,cache层里保存了某个key为null之后,storage层里新增了这个key的数据,就会导致短期时间内都只返回null。
  • 布隆过滤器:将所有可能存在的key放在一个足够大的bitmap中,则不存在的key会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力,例如电话号码等

更多好文

请扫描下面二维码

欢迎关注~

猜你喜欢

转载自juejin.im/post/5bbd7c895188255c38537fc1