缓存穿透
当客户端向服务器发送请求的时候,缓存和数据库都没有数据,缓存不会生效,所有请求都会走数据库,就会导致数据库压力过大,很有可能会造成数据崩溃的问题。
解决思路
编码
以查询商铺为例
/**
* 根据id查询商铺信息
* @param id
* @return
*/
@Override
public Result queryById(Long id) {
//1.从redis查询缓存
String jsonStr = stringRedisTemplate.opsForValue().get(CACHE_SHOP_KEY + id);
//命中
//2.判断是否存在
if (StrUtil.isNotBlank(jsonStr)){
//3.存在,直接返回
return Result.success(JSONUtil.toBean(jsonStr, new TypeReference<Shop>() {
},true));
}
//如果redis存储的是""空字符串,在这里还要进行一次判断 不应该去查询数据库,而是直接返回
if (jsonStr != null){ //
return Result.error("商铺信息不存在");
}
//未命中
//4.不存在,从数据库中查询
Shop shop = this.getById(id);
//5.不存在,返回错误
if (ObjectUtil.isNull(shop)){
//将空值写入redis
stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id,"",CACHE_NULL_TTL,TimeUnit.MINUTES);
return Result.error("商铺信息不存在");
}
//6.存在,缓存在redis中
stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);
//7.返回
return Result.success(shop);
}
以上是使用缓存空对象的方法来解决,还有布隆过滤;增加id复杂度,避免id被猜测的可能性等等一系列的方法来解决。