Redis实战-缓存穿透、缓存雪崩、缓存击穿和缓存并发的区别和解决方案
正常处理流程
客户端请求正常的时候,先读缓存,如果数据命中,则返回缓存的值;否则,把从存储层中读取出来的数据缓存至缓存,同时返回客户端。但是,为了保证系统高可用和高性能,设计一个缓存系统时必须考虑的要素包括缓存穿透、缓存击穿、缓存雪崩和缓存并发等。这里,小编给大家简明扼要地综述一下它们的基本概念和解决策略。
缓存穿透
基本概念:客户端访问缓存和数据库中都没有的数据,如果系统不对其缓存,就出现了缓存穿透。流量大时会导致存储层挂掉。
简述:缓存中不存在的数据洪水猛兽般袭来,访问穿透到存储层。
解决方案:
-
缓存空对象。
对于未命中缓存和存储层的数据,设置默认值和五分钟左右的有效期(有效期根据业务需要设置)。
-
使用布隆过滤器。
缓存击穿
基本概念:一个缓存key是热点数据,在不停的扛着大并发,但过期那一刻持续的大并发就穿破缓存,导致存储层请求量瞬间飙高。
解决方案:
-
使用互斥锁。
在发现缓存失效的时候(判断拿出来的值为空),不是立即去请求DB,而是成功添加互斥锁后再请求DB并回设缓存;否则,就重试查询缓存的方法。 -
提前使用互斥锁。
在value内部设置1个超时标签(timeout1),当从cache读取到timeout1发现它已经过期的时候,马上延长timeout1并重新设置到cache,然后再从数据库加载数据并设置到cache中。
缓存击穿和缓存雪崩的区别在于前者针对某一个key,缓存雪崩则是针对很多key。缓存key在某个时间点过期的时候,恰好有大量的并发请求过来,这些请求发现缓存过期就从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
缓存雪崩
基本概念:缓存服务器某个节点宕机或断网或者在某一个时间段大量缓存集体失效,请求全部转发到DB,DB压力骤增而引起雪崩。
解决方案:
-
使缓存过期时间呈泊松分布。
-
开启缓存过期事件监听和异步更新策略。
监听到缓存过期时,异步起一个线程去读数据库,更新缓存。
修改Redis配置文件,开启过期事件监听:使notify-keyspace-events
的值为Ex
。
缓存并发
基本概念:多个redis的client同时set key引起的并发问题。其实redis自身就是单线程操作,多个client并发操作,按照先到先执行的原则,先到的先执行,其余的阻塞。当然,另外的解决方案是把set操作放在队列中使其串行化,必须一个一个的执行。
Reference
https://baijiahao.baidu.com/s?id=1655304940308056733&wfr=spider&for=pc