Redis之缓存更新策略

本文介绍了Redis缓存更新的两种常见策略及其存在的问题,包括先更新数据库再更新缓存和先更新数据库再删除缓存,并提出了分布式锁的解决方案。此外,还讨论了缓存失效(击穿)、缓存穿透、冷数据重建缓存和缓存雪崩等异常情况,给出了相应的解决方案,如设置随机过期时间、缓存空值、布隆过滤器、限流和高可用策略等。
摘要由CSDN通过智能技术生成

一、常见的缓存更新策略以及存在问题

  1. 先更新数据库然后更新缓存,就像下面的代码:
    public Product update(@Valid @NotNull(message = "商品更新对象不能为null") Product product){
   
        Product productResult = productDao.update(product);
        redisUtil.set(getCacheKey(productResult.getId()),productToJsonString(productResult),getCacheKeyTimeout(), TimeUnit.HOURS);
        return productResult;
    }

上面更新逻辑正常的执行顺序如下:
在这里插入图片描述
但是没有在这里做任何的同步也可能会出现下面的执行顺序:
在这里插入图片描述
如何解决上面的问题呢?要解决上面的问题首先需要分析问题出现的根本原因是操作数据库和操作redis这两个操作不是原子的,假如在服务是单节点的情况下可与直接通过java的内置锁或者基于AQS实现的锁保证只有一个线程可以进入可以接受上述问题。假如是在分布式的环境下呢,就需要加上分布式锁,实现的逻辑如下:

    public Product update(@Valid @NotNull(message = "商品更新对象不能为null") Product product){
   

        Product productResult = null;
        RLock productUpdateLock = redisson.getLock(RedisKeyPrefixConst.PRODUCT_CACHE_UPDATE_PREFIX + product.getId());

        productUpdateLock.lock();
        try {
   
            productResult = productDao.update(product);
            redisUtil.set(getCacheKey(productResult.getId()),productToJsonString(productResult),getCacheKeyTimeout(), TimeUnit.HOURS);
        }catch (Exception e){
   
            //处理业务异常
        }finally {
   
            productUpdateLock.unlock();
        }

        return productResult;
    }

通过上面的这种加锁逻辑保证每次只能有一个线程执行操作数据然后操作缓存就不会出现缓存数据不一致的情况。
2. 先更新数据库然后删除缓存,具体的实现逻辑如下:

    public Product update(@Valid @NotNull(message = "商品更新对象不能为null") Product product){
   
        Product productResult = productDao.update(product);
        redisUtil.delete(getCacheKey(productResult.getId()));
        return productResult;
    }

正常的执行流程
在这里插入图片描述
异常的执行流程
在这里插入图片描述
虽然更新数据库然后删除缓存这种方式是使用的最多但是依然存在数据库和缓存不一致的情况,出现这种情况的原因是查询数据和更新数没有做同步在这里也是一样加上一把分布式锁就行:

public Product update(@Valid @NotNull(message = "商品更新对象不能为null") Product produ
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值