缓存穿透,缓存击穿,缓存雪崩问题及解决方法

缓存穿透:

  • key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。
  • 举例:比如说我的key是数字(123),但是网络攻击者频繁的用字符串(abc)去获取缓存。导致永远无法命中缓存,直接查取的数据库。缓存的意义就是为了减少数据库压力。这样就失去了意义。
  • 如何解决:布隆过滤器是redis提供的一种数据结构。他可能在海量数据中(上千万)来判断当前值存不存在。布隆过滤器准确率不是百分之百。大概98%左右。另外也有一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。

 缓存击穿

  • key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从数据库加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把数据库压垮。
  • 例子:比如说我的官网数据是热点数据,在并发非常高的时候,比如说高考报名的时候,这个是官网数据缓存过期了。
  • 解决方案:一些非常高频的热点数据,不设置过期时间。并且开启定时任务定期查看缓存有没有被删除,如果缓存不存在了,更新缓存。
  • 注意:不设置过期时间只能保证redis不会删,但是不能保证其他服务有没有可能删。

缓存雪崩

  • 在使用缓存时,通常会对缓存设置过期时间,一方面目的是保持缓存与数据库数据的一致性,另一方面是减少冷缓存占用过多的内存空间。但当缓存中大量热点缓存采用了相同的实效时间,就会导致缓存在某一个时刻同时实效,请求全部转发到数据库,从而导致数据库压力骤增,甚至宕机。从而形成一系列的连锁反应,造成系统崩溃等情况,这就是缓存雪崩
  • 解决方案:key的过期时间做合理的规划,对于高频数据,不设置过期时间。

什么情况下要考虑这三个问题?

  • 看用户量和并发量和数据量(单表数据达到200多万)这三者的量级大。

小结

缓存雪崩和缓存击穿是因为数据不存在于缓存中(或服务异常获取不到),导致大量请求访问数据库,从而导致数据库压力骤增,甚至崩溃。

而缓存穿透则是由于数据本身就不存在,导致缓存没有进行数据缓存,流量进入数据库层。

针对不同的缓存异常场景,可选择不同的方案来进行处理。当然,除了上述方案,我们还可以限流、降级、熔断等服务层的措施,也可以考虑数据库层是否可以进行横向扩展,当缓存异常发生时,确保数据库能够抗住流量,不至于让整个系统崩溃。


 

你可能感兴趣的:(缓存,redis,数据库)