缓存常见场景
一缓存击穿
在平常的高并发系统中,大量请求同时查询一个key时,此时key正好失效了,就会导致大量的请求都达到数据库上面去,这种场景我们成为缓存击穿。
影响:会造成某一时刻数据库流量过大,压力剧增
解决方案:
1.设置热点数据永不过期
2.击穿原因是多个线程同时查询数据库,可在第一个查询数据的请求上使用一个互斥锁,其他线程拿不到锁进行等待,等第一个线程返回后做缓存,后边线程发现缓存中有数据后直接走缓存
二缓存穿透
用户查询数据,在数据库中没有,自然缓存中也不会有,因此缓存中不存在对应的key和value,每次都要去数据库查询然后返回空(相当于进行了两次无用查询),这样请求就绕过缓存直接查询数据库
影响:增加数据库压力、大量不存在的key刷单时容易造成数据库宕机
解决方案:
1.缓存空值:如果一个查询返回空的数据,我们仍然把这个空的结果进行缓存,但是他的过期时间会很短,比方说5分钟以内,通过设置默认值到缓存,再次查询时缓存中就有值了,而不会继续请求数据库
2.采用BloomFilter:
三缓存雪崩
如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落到数据库上,造成了缓存雪崩,由于原有缓存实失效,新缓存未到期间所有缓存的请求都去查询数据库,而对数据库cpu和内存造成巨大压力、甚至宕机
解决方案:
1)加锁排队:mutext互斥锁,redis的setnx
2)数据预热:缓存系统上线后将相关的缓存数据提前加载到缓存系统。
3)双层缓存策略:C1为 原始缓存、C2拷贝缓存、C1失效时可以访问C2,C2缓存失效时间设置为短期,C1设置为长期
4)定时更新缓存策略:实时性要求不高的缓存,容器启动初始化加载、采用定时任务更新或者移出缓存
5)设置不同的过期时间;让缓存失效时间尽量均匀