文章目录
- 1、缓存穿透
- 2、常见的解决方案有两种:
- 2.1、缓存空对象
- 2.2、布隆过滤器
- 3、编码解决商铺查询的缓存穿透问题
- 3.1、queryById
- 3.2、RedisConstants.java
1、缓存穿透
缓存击穿是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。
2、常见的解决方案有两种:
2.1、缓存空对象
优点:实现简单,维护方便
缺点:额外的内存消耗、可能造成短期的不一致
2.2、布隆过滤器
优点:内存占用较少,没有多余key
缺点:实现复杂、存在误判可能
3、编码解决商铺查询的缓存穿透问题
3.1、queryById
@Override
public Result queryById(Long id) {
String key = CACHE_SHOP_KEY + id;
//1、从redis查询商铺缓存
String shopJson = stringRedisTemplate.opsForValue().get(key);
//2、判断是否存在
if (StrUtil.isNotBlank(shopJson)) {
//3、存在,直接返回
Shop shop = JSONUtil.toBean(shopJson, Shop.class);
return Result.ok(shop);
}
//判断命中的是否是空值
if (shopJson != null) {
return Result.fail("店铺不存在!");
}
//4、不存在,根据id查询数据库
Shop shop = getById(id);
//5、数据库不存在,返回错误
if (shop == null) {
// 将空值写入redis
stringRedisTemplate.opsForValue().set(key, "", CACHE_NULL_TTL, TimeUnit.MINUTES);
//返回错误信息
return Result.fail("店铺不存在!");
}
//6、存在,写入redis
stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
//7、返回
return Result.ok(shop);
}
3.2、RedisConstants.java
public static final Long CACHE_NULL_TTL = 2L;
public static final Long CACHE_SHOP_TTL = 30L;
public static final String CACHE_SHOP_KEY = "cache:shop:";