缓存穿透、缓存击穿、缓存雪崩

缓存穿透

描述:

用户不断发起请求访问缓存和数据库中都没有的数据,如发起为id为负的数据或id不存在的数据。导致每一次请求都查询数据库。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

解决方案:

1、接口层增加校验,如用户鉴权校验,并对id做基础校验,如id<=0的直接拦截;

2、从缓存取不到的数据,在数据库中也没有取到,可以给攻击请求所访问的key设置一个null值,并设置一个较短的有效时间,(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击。

 

缓存并发

描述:

指缓存中某个key值到期,但由于高并发状态下,访问这个key的请求量较大,大量请求同时读缓存没读到数据,又同时去数据库去取数据并回写缓存,引起应用和数据库负载增大,性能降低。

解决方案:

1、设置热点数据永不过期

2、设置软过期,不使用缓存服务器提供的失效时间,而是业务层在数据中存储过期时间信息。由业务层判断是否过期并更新,在发现了数据即将过期时,将缓存的时效延长,程序可以派遣一个线程去数据库中获取最新的数据,其他线程看到延长了的过期时间就会继续使用旧数据,等派遣的线程获取最新数据后再更新缓存。

3、添加互斥锁,参考代码如下

 

PS:

1、缓存中有数据,直接第13行返回结果就行

2、缓存中没有数据,第一个线程获取锁成功,去数据库读取数据添加到缓存中。其他线程获取锁失败,休眠100ms,再次尝试从缓存中读取数据。

3、这里的示例代码是简化版本,实际使用中应该根据key值加锁,理论上线程A去数据库取key1的值不应该妨碍线程B去数据库取key2的值。

 

缓存雪崩

描述:

指缓存中数据大批量到过期时间,给后端数据库造成瞬间负载升高,甚至压垮数据库的情况。

与缓存击穿不同,缓存击穿指并发查同一条数据,而缓存雪崩是不同数据都过期了,很多范文不同key值的请求全部查询数据库。

解决方案:

1、缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。甚至是对相同的数据,不同的请求设置不同的过期时间。

2、分布式部署的缓存数据库,可以将热点数据均匀分布在不同缓存数据库中。

3、设置热点数据永远不过期。