Redis缓存穿透
什么是缓存穿透
缓存中存储的一定是数据源中存在的数据,只有数据源中存在某个数据,在初次请求之后我们才会把它放在缓存中,等待下一次请求时直接返回缓存的数据;如果数据源中不存在这个数据,那么我们也就不会对其进行缓存。对此,也就出现了缓存穿透问题。
缓存穿透,指的是大量并发请求查询的都是数据库中一定不存在的数据,那么对应的缓存中也一定不存在该数据,所以这些并发请求都回落到数据库中,进而有可能会压垮数据库,引发宕机。黑客可以利用这种漏洞去攻击某个网站
解决办法
在实际应用中有很多解决缓存穿透办法,最常见的有两种:
第一种就是我们对查询到的空结果进行缓存,但是我们设置很短的过期时间,让它在短时间内过期。这样每次请求可以从缓存中返回一个空数据,减少缓存穿透的几率
第二种就是采用布隆过滤器,将我们业务中所有可能存在的数据通过一系列hash函数分配到一个足够大的二进制向量中,将对应的位置置为1。等到我们判断某个元素是否存在时,看这些对应的位置是否为1,如果为1,则说明元素极有可能存在。因为布隆过滤器也可能会判断错误,存在一定的误算率,但是在大量数据面前这是可以接受的。
缓存击穿
什么是缓存击穿
缓存中存储的数据是有一定期限的,因为我们的数据一直在更新,这样的话对应的缓存中的数据也要更新,所以我们会设置缓存的过期时间,一旦缓存过期就会重启请求数据库中的数据,重新进行缓存。那么在缓存过期这个节点就会发生缓存击穿的问题,那什么是缓存击穿呢?
缓存击穿就是在缓存中的数据过期时,有大量的请求发了过来,由于缓存中的数据过期了,所以只能去数据库中去查询,这样的高并发很可能会压垮数据库。这就产生了缓存击穿的问题。
解决方案
缓存击穿的解决方案也有很多,在实际业务中,我们可以设置热点数据永不过期,这样的话当访问已经在缓存中的热点数据时会及时响应,访问不在缓存中的数据时可以去数据源获取,这可以在一定程度上减少缓存击穿的发生
此外,我们还可以通过使用互斥锁,也就是使用mutex。就是在缓存失效的时候,在去数据库查询最新的数据前,上一个锁(同时间的其他获取缓存操作就会被阻塞,这个阻塞只会只会影响很小的一部分请求),然后再去完成数据查询,缓存更新等操作。在redis中可以使用setnx进实现这个操作。
SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果
缓存雪崩
什么是缓存雪崩
我们在缓存中的数据都会设置缓存时间,如果大量数据设置的缓存数据一致,他们在同一时间过期,那么就会引起缓存雪崩的问题。
缓存雪崩就是当有大量数据同时过期,同时又有大量的请求,那么请求就会落到数据库,后端数据库就有可能被压垮。
解决方案
最简单的解决方案就是将缓存过期的时间分散开,避免同时过期,比如我们可以在基础过期时间上增加一个随机值,这样每一个缓存的过期时间的重复率就会降低,就很难引发群体失效事件,这就很大程度上减少了缓存雪崩的可能
缓存击穿与缓存雪崩的区别
两者的区别就是缓存击穿对应的是某个key过期时大量请求来临引发的,而缓存雪崩是大量key同时失效给后端数据库带来了大量压力。
感谢各位阅读到最后,如果写的有什么问题还请各位大神在评论区指正,一起学习,共同进步。