今天面试的时候被人问到了缓存雪崩,脑子一下炸了,突然忘了雪崩和穿透的差别了,现在整理了一下:
缓存雪崩:当缓存中大量的key在同一时刻失效,导致所有的请求都到db,这种现象叫做缓存雪崩
ok,如何避免呢?
在网上搜了一下,大概有如下的解决方案:
1 对存储缓存中的数据,设置过期时间时,添加一个随机数:即:过期时间+random(X)再添加到缓存中,这样,大量的key的缓存时间都不会一样(不排除有些一样),但是不会出现大面积的key同时失效的现象发生
2 当缓存失效之后,对大量涌入的请求进行排队,由第一个请求到db读到数据之后,放入缓存,后面的请求就可以不用到db中了
再说说缓存穿透:
缓存穿透–
说白了就是:别人通过你缓存中不存在的key,绕过缓存机制,直接请求到达db,当很多这样的请求涌入时,db是承受不了这么多请求的,导致整个应用都卡住
如何避免呢:
对一定不存在的key进行过滤。可把所有可能存在的key哈希到一个大的Bitmap中,查询时通过该bitmap过滤。
缓存击穿:
某一时刻,某个key过期时间到了,此时正好有很多请求同时涌进来,请求到db,造成系统压力
如何避免:
永不过期。
这里的“永远不过期”包含两层意思:
(1) 从redis上看,确实没有设置过期时间。
(2) 从功能上看,如果不过期,那不就成静态的了吗?所以我们把过期时间存在key对应的value里,若发现要过期或已经过期时,则通过一个后台异步线程进行缓存的构建。