正文
+ p.getId() +
"数据做了缓存"
);
return
p;
}
在这个例子里面isAllowNullValue = true表示允许换存NULL值,magnification = 10表示NULL值和非NULL值之间的时间倍率是10,也就是说当缓存值为NULL是,二级缓存的有效时间将是1个小时。
限流
应对缓存穿透的常用方法之一是限流,常见的限流算法有滑动窗口,令牌桶算法和漏桶算法,或者直接使用队列、加锁等,在layering-cache里面我主要使用分布式锁来做限流。
layering-cache数据读取流程:
数据读取流程.jpg
下面是读取数据的核心代码:
private T executeCacheMethod(RedisCacheKey redisCacheKey, Callable valueLoader) {
Lock redisLock = new Lock(redisTemplate, redisCacheKey.getKey() + "_sync_lock");
for (int i = 0; i < RETRY_COUNT; i++) {
try {
Object result = redisTemplate.opsForValue().get(redisCacheKey.getKey());
if (result != null) {
logger.debug("redis缓存 key= {} 获取到锁后查询查询缓存命中,不需要执行被缓存的方法", redisCacheKey.getKey());
return (T) fromStoreValue(result);
}
if (redisLock.lock()) {
T t = loaderAndPutValue(redisCacheKey, valueLoader, true);
logger.debug("redis缓存 key= {} 从数据库获取数据完毕,唤醒所有等待线程", redisCacheKey.getKey());
container.signalAll(redisCacheKey.getKey());
return t;
}