缓存之雪崩现象与穿透现象
一、缓存雪崩
缓存雪崩可能是因为数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。
解决思路:
1,采用加锁计数,或者使用合理的队列数量来避免缓存失效时对数据库造成太大的压力。这种办法虽然能缓解数据库的压力,但是同时又降低了系统的吞吐量(即为:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待)。
2,分析用户行为,尽量让失效时间点均匀分布。避免缓存雪崩的出现。----【具体方法:
a.将缓存时间设置的更长(设置为24h),等到半夜网站访问量少的时候,进行全部缓存的更新
b.将缓存时间设置在随机3-9小时的范围内,这样,缓存就不会同时失效,可以减少同一时间缓存失效量,减少对DB的压力(即为:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀)
】
3,如果是因为某台缓存服务器宕机,可以考虑做主备,比如:redis主备,但是双缓存涉及到更新事务的问题,update可能读到脏数据,需要好好解决(即为:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期)。
二、缓存穿透
缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库中查询。
解决思路:
1,如果查询数据库也为空,直接设置一个默认值【比如:查询结果为空的,给直接指定之为'kk',并存入缓存中,缓存时间设置短一点;到该key对应的数据insert了之后清理'kk'缓存,重新缓存】存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库,这种办法最简单粗暴。
2,根据缓存数据Key的规则。例如我们公司是做机顶盒的,缓存数据以Mac为Key,Mac是有规则,如果不符合规则就过滤掉,这样可以过滤一部分查询。在做缓存规划的时候,Key有一定规则的话,可以采取这种办法。这种办法只能缓解一部分的压力,过滤和系统无关的查询,但是无法根治。
3,采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的BitSet中,不存在的数据将会被拦截掉,从而避免了对底层存储系统的查询压力。关于布隆过滤器,详情查看:基于BitSet的布隆过滤器(Bloom Filter)
大并发的缓存穿透会导致缓存雪崩!
------------------------------------------------------------------------------------------------------------------------------
案例:
一个上千万PV的门户网站,缓存生命周期设置了6小时,当等到6小时缓存失效后,之前放到缓存的数据,都转到DB中查询,这时候,DB的压力急剧上升,最后导致DB崩溃
以上案例解决方法:
1.将缓存时间设置的更长,等到半夜网站访问量少的时候,进行全部缓存的更新
2.将缓存时间设置在随机3-9小时的范围内,这样,缓存就不会同时失效,可以减少同一时间缓存失效量,减少对DB的压力
推荐此链接,可参考: https://segmentfault.com/a/1190000005886009