缓存穿透、缓存雪崩、缓存击穿解决方法
2018-12-04 11:31
459 查看
缓存穿透:
- 缓存穿透:查询不存在的数据,不会写入缓存,因此就会不断的去查询,在流量大的时候,数据库可能就会挂了。
- 解决方法:
-
布隆过滤器
- 将查询结果为空的数据写入缓存,设置过期时间短一些
缓存雪崩:
- 缓存雪崩:大量的key设置了相同的过期时间,在某时刻全部失效,大量key请求数据库,数据库!雪崩!
- 解决方法:在缓存过期时间上加一个随机值时间,使数据的过期时间分散,不在同一时刻失效
缓存击穿:
-
缓存击穿:某些key在缓存将要过期的时候,碰巧有大量的并发请求这个key,这时缓存已过期,就会从数据库查询数据,大量的并发请求涌向数据库,KO!数据库败!
-
解决方法:
互斥锁(mutex key):访问key之前,采用SETNX(set if not exists)设置锁,来锁住后边数据的查询,然后对这个key查询数据库并设置缓存,释放锁,其他数据查询缓存
特点:思路简单,可以保持查询结果一致性,但:代码复杂、可能死锁、线程池阻塞。
- “提前”使用互斥锁:
设置超时值,超时值比实际数据过期的时间值小,当从缓存中读到超时值,立马延长缓存的超时值,然后读取数据库的数据并设置缓存
特点:一致性,缺点同互斥锁 - 设置缓存“永不过期”:
如果发现要过期了,后台异步,其他数据照样输出老的值,这条数据构建缓存:从库里更新数据到缓存,返回结果
特点:不会阻塞,但:查询结果可能不一致、每个值都要有超时值,代码复杂、多个值占用空间大 - 分级缓存:
一级缓存、二级缓存,一级缓存失效时间短。
先请求一级,如果一级失效未查询到则加锁,然后从数据库读取数据更新到一级、二级缓存中,在此期间,其他的数据请求二级缓存
特点:不阻塞,但:会占用额外的缓存空间、查询结果可能不一致
引用:
业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。
SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果”
相关文章推荐
- 最佳实践 缓存穿透,瞬间并发,缓存雪崩的解决方法
- 缓存穿透,缓存雪崩,缓存击穿的解决方案
- 缓存穿透,缓存击穿,缓存雪崩
- 缓存穿透,缓存击穿,缓存雪崩解决方案分析
- 缓存穿透和缓存雪崩的预防和解决-Redis
- 什么是缓存穿刺和缓存雪崩?如何解决缓存穿透,缓存雪崩
- 【转载】缓存穿透,缓存击穿,缓存雪崩解决方案分析
- 缓存穿透,缓存击穿,缓存雪崩解决方案分析
- 缓存穿透,缓存击穿,缓存雪崩解决方案分析
- 《redis学习》-- 缓存穿透和缓存雪崩的预防和解决
- 缓存穿透,缓存击穿,缓存雪崩解决方案分析
- 缓存击穿、缓存穿透和缓存雪崩
- 缓存穿透与缓存雪崩 及解决办法
- 缓存穿透,缓存雪崩,缓存击穿解决方案分析
- 缓存雪崩和缓存穿透问题解决方案
- 缓存穿透,缓存击穿,缓存雪崩解决方案分析
- 《redis学习》-- 缓存穿透和缓存雪崩的预防和解决
- 缓存更新策略以及缓存击穿、雪崩、穿透
- 缓存穿透,缓存击穿,缓存雪崩解决方案分析
- 缓存穿透、缓存击穿、缓存雪崩解决方案分析