redis实战(商品查询缓存)

根据id查询商品:

添加redis缓存(增强读写功能)步骤

1.从redis中获取商品信息,判断信息是否存在

2.若存在则从redis中获取,不存在则直接查询数据库

3.若数据库中不存在则返回错误信息

4.若数据库中存在则同同样将信息存入redis中

controller层

复制代码
    @GetMapping("/{id}")
    public Result queryShopById(@PathVariable("id") Long id) {
        return shopService.queryById(id);
    }

service层

复制代码
@Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Result queryById(Long id) {
        String key=CACHE_SHOP_KEY+id;
        //从redis查询商品缓存
        String shopJson = stringRedisTemplate.opsForValue().get(key);

        //判断是否命中,若命中
        if(StrUtil.isNotBlank(shopJson)){
            Shop shop = JSONUtil.toBean(shopJson, Shop.class);
            return Result.ok(shop);
        }
        //判断命中是否为空值
        if(shopJson!=null){
            //返回一个错误信息
            return Result.fail("店铺不存在");
        }

        //若不存在,查询数据库
        Shop shop = getById(id);

        if(shop==null){
            //将空值写入redis
            stringRedisTemplate.opsForValue().set(key,"",CACHE_NULL_TTL,TimeUnit.MINUTES);
            return Result.fail("店铺不存在");
        }
        //存入redis
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL, TimeUnit.MINUTES);

        return Result.ok(shop);
    }

有可能发生数据库和redis中信息存储不一致的情况,即缓存更新问题

对于低一致性的需求:可以使用内存淘汰,例如商品店铺的查询缓存

对于高一致性的需求:使用主动更新,并以超时剔除为兜底方案,例如商品详情查询的缓存

然后应该先操作数据库,再删除缓存

查询店铺

controller类

复制代码
    @GetMapping("/{id}")
    public Result queryShopById(@PathVariable("id") Long id) {
        return shopService.queryById(id);
    }

service类

复制代码
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Result queryTypeList() {
        String key=CACHE_SHOP_TYPE_KEY;
        //从redis中读取缓存
        String type = stringRedisTemplate.opsForValue().get(key);

        //判断是否命中缓存
        if(StrUtil.isNotBlank(type)){
            //若存在
            List<ShopType> list = JSONUtil.toList(type, ShopType.class);
            return Result.ok(list);
        }

        //若不存在,查找数据库
        List<ShopType> shopTypes = query().orderByAsc("sort").list();
        if(shopTypes==null){
            return Result.fail("分类不存在!");
        }

        //存入redis
        stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shopTypes));

        return Result.ok(shopTypes);
    }

还需考虑缓存穿透问题

解决方案

1.从redis中获取信息,判断信息是否存在(再判断是否为空值)

2.若存在则从redis中获取,不存在则直接查询数据库

3.若数据库中不存在则设置为空值存入redis并设置有效时长

4.若数据库中存在则同同样将信息存入redis中

缓存雪崩

相关推荐
Derek_Smart13 分钟前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP1 小时前
MyBatis-mybatis入门与增删改查
java
孟陬4 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
想用offer打牌4 小时前
一站式了解四种限流算法
java·后端·go
华仔啊5 小时前
Java 开发千万别给布尔变量加 is 前缀!很容易背锅
java
也些宝6 小时前
Java单例模式:饿汉、懒汉、DCL三种实现及最佳实践
java
Nyarlathotep01136 小时前
SpringBoot Starter的用法以及原理
java·spring boot
wuwen56 小时前
WebFlux + Lettuce Reactive 中 SkyWalking 链路上下文丢失的修复实践
java
SimonKing7 小时前
GitHub 10万星的OpenCode,正在悄悄改变我们的工作流
java·后端·程序员