缓存穿透、缓存并发、缓存雪崩

缓存穿透

缓存穿透指的是使用不存在的key值进行大量的高并发查询,导致缓存无法命中,每次请求都要穿透到后端数据库系统进行查询,数据库压力过大,甚至使数据库服务被压死。

解决方法:

1、可以将空值缓存起来,再次接收到同样的查询请求时,如果命中缓存并且值为空,就直接返回,不会透传。

2、在封装的缓存SET和GET部分增加个步骤,如果查询一个KEY不存在,就已这个KEY为前缀设定一个标识KEY;以后再查询该KEY的时候,先查询标识KEY,如果标识KEY存在,就返回一个协定好的非false或者NULL值,然后APP做相应的处理,这样缓存层就不会被穿透。当然这个验证KEY的失效时间不能太长。

3、对输入的参数进行过滤,如果使用id进行查询,但是id不符合规定直接拒绝。

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

缓存并发

缓存并发是发生在高并发的场景下,当一个缓存key过期时,因为访问这个缓存key的请求量较大,那么多个请求同时发现缓存过期,因此多个请求会同事访问数据库查询最新数据,并回写,负载增加,性能降低,甚至压死。

还有一种情况。就是我们使用token进行认证。高并发情况下,A发现token过期,会去申请token1进行更新,但是同时B也发现了token过期,此时它再申请的token2会把token1失效化,token1失效后再次请求token3,会把token2失效化,最后就发现谁都认证不了了。

解决方法:

1、分布式锁,保障对于每一个key同时只有一个线程去查询后端服务,其他线程没有访问的权限,所以等待即可。

2、本地锁,原理同上,只是这种方法只能限制一个服务节点只有一个线程去数据库进行查询,但是如果多个服务节点就无法解决缓存并发的问题了。

3、软过期,对缓存中的数据设置失效时间,就是不用缓存服务提供的过期时间,而是业务层在数据中存储过期时间信息,由业务程序判断是否过期并更新,如果发现数据即将过期,那么将缓存时效延长,程序派遣一个线程去获取最新的,其他线程看到延长了过期时间,就不会认为它需要更新了,就会使用旧的数据。等派遣的线程获取最新数据之后,再更新缓存。

4、异步更新服务设置软过期的缓存。

缓存雪崩

缓存雪崩指的是缓存服务器重启或者大量缓存集中再某一个时间段内失效,给后端数据库造成瞬时的负载升高的压力,甚至压垮数据库。

解决方法:

设置不同的失效时间避免同一时段大量失效。

原文地址:https://www.cnblogs.com/hekiraku/p/12049110.html