缓存系列文章--5.缓存穿透问题
| 解决缓存穿透 | 适用场景 | 维护成本 |
| 缓存空对象 | 1. 数据命中不高 2. 数据频繁变化实时性高 |
1.代码维护简单 2.需要过多的缓存空间 3. 数据不一致 |
| bloomfilter或者压缩filter提前拦截 | 1. 数据命中不高 2. 数据相对固定实时性低 |
1.代码维护复杂 2.缓存空间占用少 |
package com.carlosfu.service;
import org.apache.commons.lang.StringUtils;
import com.carlosfu.cache.Cache;
import com.carlosfu.storage.Storage;
/**
* 某服务
*
* @author carlosfu
* @Date 2015-10-11
* @Time 下午6:28:46
*/
public class XXXService {
/**
* 缓存
*/
private Cache cache = new Cache();
/**
* 存储
*/
private Storage storage = new Storage();
/**
* 模拟正常模式
* @param key
* @return
*/
public String getNormal(String key) {
// 从缓存中获取数据
String cacheValue = cache.get(key);
// 缓存为空
if (StringUtils.isBlank(cacheValue)) {
// 从存储中获取
String storageValue = storage.get(key);
// 如果存储数据不为空,将存储的值设置到缓存
if (StringUtils.isNotBlank(storageValue)) {
cache.set(key, storageValue);
}
return storageValue;
} else {
// 缓存非空
return cacheValue;
}
}
/**
* 模拟防穿透模式
* @param key
* @return
*/
public String getPassThrough(String key) {
// 从缓存中获取数据
String cacheValue = cache.get(key);
// 缓存为空
if (StringUtils.isBlank(cacheValue)) {
// 从存储中获取
String storageValue = storage.get(key);
cache.set(key, storageValue);
// 如果存储数据为空,需要设置一个过期时间(300秒)
if (StringUtils.isBlank(storageValue)) {
cache.expire(key, 60 * 5);
}
return storageValue;
} else {
// 缓存非空
return cacheValue;
}
}
}