一、缓存击穿
问题:缓存中某一个key对应的缓存数据过期,无法命中缓存直接查询数据库,导致数据库压力增大。
解决方案:
(1)互斥锁。
无法命中缓存,首先抢互斥锁,当获取到互斥锁,再进行查询数据库的操作,并且放入缓存;否则,一直重试获取缓存的方法,或者直接返回空。
场景:并发量不高。
(2)异步更新缓存。
无法命中缓存,首先创建异步任务进行更新缓存,然后直接返回为空。
优点:不会阻塞当前线程。
缺点:牺牲数据一致性。
场景:数据一致性要求不高。
(3)将热点数据设置为永久缓存。
二、缓存雪崩
问题:缓存中大量key对应的缓存数据过期,无法命中缓存直接查询数据库,导致数据库崩溃。
解决方案:
(1)将热点数据设置为永久缓存。
(2)将缓存失效时间设置为随机时间。
三、缓存穿透
问题:缓存中某一个key不存在,数据库中也不存在,无法命中缓存直接查询数据库,导致数据库压力增大。
解决方案:
(1)空值缓存。
将key在缓存中对应的值设置为空。
注意:为确保数据最终一致性,key必须设置过期时间,防止这个key的数据后面真实存在,但是这个key的值始终为空,导致数据不一致的情况出现。
场景:key不多,并且可以预测。
(2)布隆过滤器(BloomFilter)。
把有数据的key都放到BloomFilter中,查询时首先去BloomFilter判断key是否存在,如果不存在就直接返回空。
布隆过滤器是一种数据结构,特点是高效地插入和查询。
可以明确:“某个东西一定不存在或者可能存在”。
场景:key只增加不减少,或者全部删除。