黑马点评项目 P35-P47 商铺查询缓存练习

文章介绍了如何使用Redis进行缓存查询,包括从Redis和数据库的查询顺序、缓存与数据库的双写一致性选择先更新数据库再删除缓存的方法、防止缓存穿透的空对象缓存策略、处理缓存雪崩的随机时间戳和集群方案以及应对缓存击穿的互斥锁和逻辑过期时间方法。此外,还提供了互斥锁的实现和测试方法。

1.1 商铺查询

  1. 根据商铺ID查询

  1. 从 redis 中查询商铺,如果没有就从数据库查询然后存入 reids

/**
     * 查询单个店铺
     * @param id 店铺ID
     * @return
     */
    @Override
    public Result queryShopById(Long id) {

        // 1.从 redis 中查询
        String cacheShopJson = stringRedisTemplate.opsForValue().get(RedisConstants.CACHE_SHOP_KEY + id);
        if(StrUtil.isNotBlank(cacheShopJson)) {
            // 存在直接返回
            return Result.ok(JSONUtil.toBean(cacheShopJson,Shop.class));
        }

        // 2.缓存没有的话从数据库查询
        QueryWrapper<Shop> shopQueryWrapper = new QueryWrapper<>();
        shopQueryWrapper.eq("id",id);
        Shop shop = shopMapper.selectOne(shopQueryWrapper);

        // 3.设置到 redis 里给后面做缓存用
        stringRedisTemplate.opsForValue().
                set(RedisConstants.CACHE_SHOP_KEY + id,
                        JSONUtil.toJsonStr(shop),
                        RedisConstants.CACHE_SHOP_TTL,
                        TimeUnit.MINUTES);

        return Result.ok(shop);
    }

1.2 商铺缓存与数据库的双写一致

两种方法

  • 先更新数据库,删除缓存,写入缓存

  • 先删除缓存,更新数据库,写入缓存

我们这里选用第一种

  1. 缓存命中直接返回,如果没有命中缓存就从数据库查询然后写入缓存

  1. 都存在着线程安全的问题

  1. 更新完之后会删除缓存,后续查询的时候就会没有命中缓存,然后就去数据库查询写入缓存

/**
     * 先操作数据库在更新
     * @param shop
     * @return
     */
    @Override
    @Transactional
    public Result update(Shop shop)
    {
        Long id = shop.getId();
        if(id == null) { return Result.fail("店铺ID不能为空"); }

        // 1.更新数据库
        updateById(shop);
        // 2.删除缓存
        stringRedisTemplate.delete(RedisConstants.CACHE_SHOP_KEY + id);
        return Result.ok();
    }
}

1.3 缓存穿透

客户端请求的数据,缓存和数据库中都不存在

方案

  • 缓存空对象

优点 : 实现简单,维护方便

缺点 : 额外的内存消耗

  • 布隆过滤器

优点 : 内存占用少,没有多余的key

缺点 : 实现复杂.可能存在误判

1.3.1 实现缓存空对象

  1. key - 前缀 + ID

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值