缓存穿透:
产生原因:客户端请求的数据在数据库和缓存中都不存在,这样的缓存永远不会生效,客户端的请求会直接打到数据库上面。
解决方案:
一、缓存空对象:对于不存在的数据也在redis里面建立,设置为空并设置一个较短TTL时间。优点:实现简单,维护方便。缺点:额外的内存消耗,短期内数据不一致。
二、布隆过滤: 利用布隆过滤算法,在请求进入redis之前先进行判断,若不存在则直接不进入redis。优点:内存占用少。缺点:实现复杂,存在误判的可能性。
三、其他:做好数据的基础格式校验,加强用户权限校验,做好热点参数的限流。
缓存雪崩:
产生原因:同一时间大量的key同时失效或者redis服务宕机,导致大量请求到达数据库,带来巨大的压力。
解决方案:
一、①给不同key的TTL添加随机值。②利用redis集群增加服务的可用性。③给缓存业务增加降级限流策略。④给业务增加多级缓存
缓存击穿:
产生原因:
一、热点key:同一时间段被高并发访问。缓存重建时间较长。
二、热点key突然过期,因为重建耗时长,在这段时间内大量请求落到数据库,带来巨大压力。
解决方案:
方案一、互斥锁:在缓存重建的时候加一把锁,确保重建的时候只有一个线程执行,其他线程等待。 优点:实现简单,没有过多消耗内存,一致性好。缺点:等待导致性能下降,有死锁风险。
方案二、逻辑过期:热点key永不过期,而是给热点key设置一个逻辑过期时间,查询数据时对逻辑过期时间进行判断,是否达到重建缓存标准。重建缓存也通过互斥锁保持单线程执行。重建缓存利用单线程异步执行;其他线程无需等待,查询到旧数据即可。优点:线程无需等待,性能好。缺点:有额外内存消耗,实现复杂。