赞
踩
一、缓存雪崩
1、概念
缓存雪崩就是在某一时刻,缓存集大量失效。所有流量直接打在数据库上,对数据库造成巨大压力
2、场景
电商抢购、比如抢购0点开始1点结束,在1点时大量缓存同时失效,这个时候就会造成缓存雪崩的现象
3、解决方案
加锁/队列:虽然能降低数据库压力,但同时响应也很慢
缓存标记:给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,如果缓存标记失效,则更新数据缓存
缓存过期时间错开:设置缓存时间错开,可以在设置过期时间的时候,加一个一定范围内的随机值错开
4、注意
缓存雪崩强调的是多个key的解决失效,解决方案的核心原则是让key之间的失效时间分布更加均匀,避免集体失效的情况
二、缓存穿透
1、概念
缓存穿透就是在缓存中不存在,然后直接在数据库中查询的现象
2、场景
故意攻击、比如查询商品序号为正数,但请求方总是请求大量的负数,导致缓存无效,全部流量都打在数据库中,如果某一时刻流量过大,则会导致数据库崩溃
3、解决方案
布隆过滤器:布隆过滤器会判断某个元素是否在某个几个中
缓存控制:可以把一些不符合要求的数据的key值设置为NULL,但是需要设置过期时间
4、注意
缓存穿透强调获取本不存在的缓存数据,请求必然会越过缓存层直接到达缓存层,解决方案的核心原则是过滤这些非法业务请求,与是否是热点数据、缓存失效时间等因素没有关系
三、缓存击穿
1、概念
缓存击穿就是缓存热点key在某个时间点过期的时候,恰好这个时间点对这个key有大量的并发请求过来,这些请求发现缓存过期会从数据库加载数据并设到缓存,可能会压垮数据库
2、解决方案
使用互斥锁(mutex key):在缓存失效的时候,不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法
"提前"使用互斥锁(mutex key):在value内部设置1个超时值(timeout1), timeout1比实际的memcache timeout(timeout2)小。当从cache读取到timeout1发现它已经过期时候,马上延长timeout1并重新设置到cache。然后再从数据库加载数据并设置到cache中
"永远不过期":把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建
资源保护:采用netflix的hystrix,可以做资源的隔离保护主线程池
3、注意
缓存击穿强调热点key的失效,导致某一时刻大量请求会直接到DB层,解决方案的核心原则是规避数据库的并发操作
四、缓存预热
1、概念
系统上线后,先将相关的数据构建到缓存中,避免用户请求的时候直接查库
2、场景
秒杀活动前将商品信息刷新到缓存中
五、缓存更新
1、概念
缓存更新是指缓存中暂存的数据只是一个副本,需要保证副本与主数据之间的数据一致性,需要进行缓存更新
2、解决方案
先删缓存,再更新数据库:逻辑问题,并发操作,会导致缓存中数据变成脏数据
先更新数据库,在删缓存:常用方案,同样不够完美,但是发生的概率小,虽然也会导致缓存中数据变成脏数据
先更新数据库,再更新缓存:读性能好,写性能较低,并发操作,也会导致缓存中数据变成脏数据
read/write through:数据库由缓存代理,应用只感知缓存而不感知数据库
Write Behind Caching(写回):在更新数据的时候,只更新缓存,不更新数据库,缓存异步批量更新数据库,数据不是强一致性的,而且可能会丢失
六、缓存降级
1、概念
缓存降级是指缓存失效或缓存服务器挂掉的情况下,不去访问数据库,直接返回默认数据或访问服务的内存数据。降级的最终目的是保证核心服务可用,即使是有损的,防止Redis服务故障,导致数据库跟着一起发生雪崩问题
2、解决方案
一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级
警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警
错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级
严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级
文章仅作为个人学习整理
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。