13-分布式缓存面试题+SpringCache解决方案
上一章讲了对SpringCache的常用注解的介绍与使用方法,相信对SpringCache的使用也更为清晰了,接下来讲一下使用SpringCache来解决分布式缓存最热门的面试题(缓存击穿+缓存雪崩+缓存穿透)
什么是缓存击穿?
缓存击穿就是某个热点key的缓存失效了,简单来说就是缓存中没有但数据库中有的数据,当某一个热点key缓存过期了,而这时又有大量的请求发送过来,这个时候请求就会直接击穿到数据库,造成瞬时数据库请求量大、压力增大。
如何预防缓存击穿呢?
(1)设置热点数据不过期
(2)设置定时任务及时更新缓存
(3)设置互斥锁
使用SpringCache解决缓存击穿问题
可以在注解体中添加缓存的同步sync,sync可以指示底层缓存锁住,使只有一个线程可以进入计算,而其他的线程是阻塞状态,直到返回结果更新到缓存中去。当然实现的方法有很多,这里因为使用的是SpringCache,所有使用SpringCache来解决这种问题。
@Cacheable(value = {"product"},key ="#root.args[0]",
cacheManager ="customCacheManager", sync=true)
什么是缓存雪崩?
上面讲了缓存击穿,缓存击穿说的是在某一个热点key过期。而缓存雪崩只的是多个热点key都过期,大量的key设置的相同的过期时间,导致缓存在同一时间全部失效。这时大量请求发送,造成瞬时数据库请求量大、引起雪崩。
如何预防缓存雪崩?
(1)给数据的过期时间设置成随机,防止同一时间大量数据过期的现象
(2)设置热点数据永不过期,定时任务定时更新缓存
使用SpringCache解决缓存雪崩问题
设置差别的过期时间,比如在自定义配置CacheManager配置多个过期时间维度,配置time-to-live。
cache:
#使⽤的缓存类型
type: redis
#过时时间
redis:
time-to-live: 3600000
# 开启前缀,默以为true
use-key-prefix: true
# 键的前缀,默认就是缓存名cacheNames
key-prefix: XD_CACHE
# 是否缓存空结果,防⽌缓存穿透,默以为true
cache-null-values: true
什么是缓存穿透?
缓存穿透就是查询一个不存在的数据,由于没有该缓存,并且出于容错考虑。比如用户发起id为“-1”的不存在数据。如果从存储层查不到数据则不写入缓存这将导致这个不存在的数据每次都要去存储层去查询,失去了缓存的意思。存在大量查询不存在的数据,可能数据库就挂掉了。这也是黑客利用不存在key频繁攻击应用的一种方式。
如何预防缓存穿透?
(1)在接口层增加校验、数据合理性校验
(2)缓存取不到的数据,在数据库中也没有获取到,这个时候可以将key-value写为key-null,设置短点的过期时间,防止同个key被一直攻击
使用SpringCache解决缓存穿透问题
因为空结果也缓存,所以在配置文件中设置一下,默认不配置condition或者unless就可以了。
cache:
#使⽤的缓存类型
type: redis
#过时时间
redis:
time-to-live: 3600000
# 开启前缀,默以为true
use-key-prefix: true
# 键的前缀,默认就是缓存名cacheNames
key-prefix: XD_CACHE
# 是否缓存空结果,防⽌缓存穿透,默以为true
cache-null-values: true
本章对分布式缓存常见的缓存问题有所了解,并使用SpringCache对着几种缓存问题给予解决办法。
本章小结:本章主要是对Redis的热门面试题缓存击穿、缓存雪崩、缓存穿透做出具体分析与如何预防,使用SpringCache对着三种问题的解决方案。