一、缓存穿透
缓存穿透是指查询一个一定不存在的数据,对于redis如果从存储层查不到数据则不会写入缓存,这就会导致这个不存在的数据每一次的请求都会到存储层去查询,这样就失去了缓存的意义,在流量大的时候,可能DB就挂掉了。如果有人利用不存在的key去频繁的攻击我们的应用,这就是漏洞。
解决方案
有很多方案可以有效的解决缓存穿透
- 采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免对低层存储系统的查询压力。
- 如果查询返回的数据为空,仍然把这个空结果进行缓存,但它的过期时间很短,最长不超过5分钟。
二、缓存雪崩
缓存雪崩是指我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。
解决方案
将缓存的失效时间分散开,比如我们可以在原有的时间的基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引起集体失效的事件。
缓存击穿
对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据,这时候就要考虑缓存击穿的问题,和缓存雪崩的区别在于这里针对某一个key的缓存,前者则是很多key。
缓存在某个时间点过期的时候,恰好这个时间点对这个key 有大量的并发请求过来,这些请求发现缓存过期后一般都会从DB加载数据并设到缓存,这个时候并发的请求可能会瞬间把后端DB压垮。
解决方案
- 使用互斥锁。使用mutex,在缓存失效的时候,不是立即去加载DB,而是先使用缓存工具的某些带成功操作返回值的操作去set一个mutex key,当操作返回成功时,在加载DB的操作并回设缓存。否则,就重试整个get缓存的方法。
- 永远不过期
- 从redis上看,确实没有设置过期时间,这就保证了,不会出现热点key过期问题,也就是“物理”不过期。
- 从功能上看,如果不过期,那不就成静态的了吗?所以我们把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建,也就是“逻辑”过期
原文出自:https://blog.csdn.net/zeb_perfect/article/details/54135506
网友评论