Redis缓存雪崩 & 缓存击穿及其解决办法

目录

一、缓存雪崩(缓存失效)

解决方式:

二、缓存击穿(即热点key问题)

解决方式:


一、缓存雪崩(缓存失效)

缓存雪崩,是指在一段时间内,缓存集中过期失效,这样会发生大量的缓存穿透,大量访问直接落到数据库上,对DB造成压力;

产生雪崩的原因之一,比如在写本文的时候,马上就要到双十二零点,很快就会迎来一波抢购,这波商品时间比较集中的放入了缓存,假设缓存一个小时。那么到了凌晨一点钟的时候,这批商品的缓存就都过期了。而对这批商品的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。

解决方式:

1. 在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

2. 可以通过缓存reload机制,预先去更新缓存,在即将发生大并发访问前手动触发加载缓存。

3. 不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

例如电商环境,对于不同热度的商品,缓存不同的周期,在同一分类中的商品,加上一个随机因子。这样能尽可能分散缓存过期时间,而且,热门类目的商品缓存时间长一些,冷门类目的商品缓存时间短一些,也能节省缓存服务的资源。

4. 做二级缓存,或者双缓存策略。A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。

 

二、缓存击穿​​​​​​​(即热点key问题)

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,由于缓存的构建需要一定时间,当缓存失效后需要重新从数据库中获取数据构建该缓存,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

ps:缓存穿透是由于大量查询一个不存在的key,缓存击穿是大量查询单一个key。

解决方式:

1. 使用互斥锁(mutex key):这种解决方案思路比较简单,就是只让一个线程构建缓存,其他线程等待构建缓存的线程执行完,重新从缓存获取数据就可以了。

2. "提前"使用互斥锁(mutex key):在value内部设置1个超时值(timeout1), timeout1比实际的memcache timeout(timeout2)小。当从cache读取到timeout1发现它已经过期时候,马上延长timeout1并重新设置到cache。然后再从数据库加载数据并设置到cache中。

3. "永远不过期":

 这里的“永远不过期”包含两层意思:

    (1) 从redis上看,确实没有设置过期时间,这就保证了,不会出现热点key过期问题,也就是“物理”不过期。

    (2) 从功能上看,如果不过期,那不就成静态的了吗?所以我们把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建,也就是“逻辑”过期。

4. 资源保护:可以做资源的隔离保护主线程池,如果把这个应用到缓存的构建也未尝不可。


参考文章:

实例解读什么是Redis缓存穿透、缓存雪崩和缓存击穿

Redis缓存雪崩、缓存穿透、热点Key解决方案和分析

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Redis)