Redis缓存之解决缓存穿透

目录

缓存穿透问题

优化后的代码示例

代码主要过程


在开发高并发的应用时,频繁访问数据库会导致性能瓶颈。基于上一篇博客的代码,我们可以通过优化来解决缓存穿透的问题。

缓存穿透问题

缓存穿透是指请求的数据在缓存和数据库中都不存在,每次请求都会直接访问数据库,从而失去了缓存的意义,导致数据库负载过高。

优化后的代码示例

下面是优化后的代码,解决了缓存穿透的问题:

@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @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);
    }
}
代码主要过程
  1. 从Redis查询缓存
    首先从Redis中查询缓存数据。

  2. 判断缓存是否存在
    判断缓存中是否存在对应的商铺数据。如果存在,直接转换为Shop对象并返回。这里存在是指键和值都不为空。

  3. 处理缓存穿透
    如果缓存中的数据为空字符串(即shopJson != nullStrUtil.isNotBlank(shopJson)为false),表示之前数据库中没有该商铺信息,为了防止缓存穿透,返回错误信息。

    if (shopJson != null) {
        return Result.fail("店铺不存在");
    }
    
  4. 查询数据库
    如果Redis中没有缓存该商铺信息,则需要从数据库中查询。通过getById(id)方法查询数据库中的商铺数据。

  5. 将空值写入Redis
    如果数据库中也不存在该商铺信息,将一个空字符串写入Redis,并设置过期时间,防止缓存穿透。

    if (shop == null) {
        stringRedisTemplate.opsForValue().set(key, "", CACHE_NULL_TTL, TimeUnit.MINUTES);
        return Result.fail("店铺不存在");
    }
    

  6. 将数据写入Redis
    如果数据库中存在该商铺信息,则将该信息转换为JSON字符串后写入Redis缓存,同样设置缓存过期时间。

    stringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL, TimeUnit.MINUTES);
    

  7. 返回数据
    最后,将查询到的商铺数据返回。

通过以上优化,我们可以有效地防止缓存穿透问题,减少数据库的压力,提高系统的性能和稳定性。希望本文对你在项目中解决缓存穿透问题有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值