缓存穿透:在高并发下,查询一个不存在的值时,缓存不会被命中,导致大量请求直接落到数据库上,如活动系统里面查询一个不存在的活动。
缓存击穿:在高并发下,对一个特定的值进行查询,但是这个时候缓存正好过期了,缓存没有命中,导致大量请求直接落到数据库上,如活动系统里面查询活动信息,但是在活动进行过程中活动缓存突然过期了。
缓存雪崩:在高并发下,大量的缓存key在同一时间失效,导致大量的请求落到数据库上,如活动系统里面同时进行着非常多的活动,但是在某个时间点所有的活动缓存全部过期。
解决方案:
- 缓存永远不过期
- 限流
- 缓存预热
- 分级缓存
- 直接缓存NULL值
sdf
asdf
限流:
常用方法有队列、加锁;令牌桶算法、漏桶算法、滑动窗口。
layering-cache主要采用 分布式锁来做限流。
多级缓存框架layering-cache介绍:
直接缓存NULL值示例如下:
//配置缓存非空值和NULL值之间的过期时间倍率
@Cacheable(value = "people", key = "#person.id", depict = "用户信息缓存",
firstCache = @FirstCache(expireTime = 10, timeUnit = TimeUnit.MINUTES),
secondaryCache = @SecondaryCache(expireTime = 10, timeUnit = TimeUnit.HOURS,
isAllowNullValue = true, magnification = 10))
public Person findOne(Person person) {
Person p = personRepository.findOne(Example.of(person));
logger.info("为id、key为:" + p.getId() + "数据做了缓存");
return p;
}
明细:
该示例表示,isAllowNullValue = true表示允许换存NULL值,magnification = 10表示NULL值和非NULL值之间的时间倍率是10,也就是说当缓存值为NULL是,二级缓存的有效时间将是1个小时。
layering-cache对NULL值进行了特殊处理,一级缓存不允许存NULL值,二级缓存可以配置缓存是否允许存NULL值,如果配置可以允许存NULL值,框架还支持配置缓存非空值和NULL值之间的过期时间倍率,这使得我们能精准的控制每一个缓存的NULL值过期时间,控制粒度非常细。当NULL缓存过期我还可以使用限流,缓存预热等手段来防止穿透。
fasdfasd