Redis缓存数据与MySql的数据不一致

1.应用与现象

Redis用作缓存是一种非常常见的方法,但是这可能导致缓存数据和数据库数据不一致的问题,例如:下面我通过redis工具栏让该方法的数据进入redis缓存

它的第一次查询结果是:

接下来我直接修改该条数据为:

我再次刷新页面后的查询结果还是:

这就造成了数据不一致问题,那怎么解决呢?

接下来我将介绍两种方法

2.解决方法

2.1延迟双删

在缓存一致性问题的解决方案中,延时双删策略(Delayed Double Deletion)是一种常见的方法。它通过在数据库更新后先删除缓存,然后在短时间延迟后再次删除缓存,来解决缓存与数据库之间的潜在数据不一致问题。

延时双删策略的步骤:

1.删除缓存:首先删除缓存中的数据。

2.更新数据库:接着更新数据库中的数据。

3.延时再删:等待一段时间后,再次删除缓存,以防止并发写导致的数据不一致问题。

将我的更新代码改成上述的延迟双删后:

    @Override
    public ResponseResult updateGoods(TGoodsEntity goods) {
        String cacheKey = "goods";
        // Step 1: 立即删除缓存
        evictCacheImmediately(cacheKey);
        // Step 2: 更新数据库
        int i = tGoodsMapper.updateGoods(goods);
        if (i > 0) {
            // Step 3: 延时后再次删除缓存
            evictCacheWithDelay(cacheKey);
            return ResponseResult.success("修改成功");
        }
        return ResponseResult.error(AppHttpCodeEnum.UPDATE_FAIL);
    }
    // 立即删除缓存的方法

    public void evictCacheImmediately(String cacheKey) {
        redisUtils.delete(cacheKey);
        System.out.println("立即删除缓存: goods::" + cacheKey);
    }
    // 延时再删缓存的方法
    @Async
    public void evictCacheWithDelay(String cacheKey) {
        scheduler.schedule(() -> {
            System.out.println("延时删除缓存: goods::" + cacheKey);
            evictCacheImmediately(cacheKey);
        }, 5, TimeUnit.SECONDS);  // 延时5秒,可以根据具体情况调整
    }

再次执行更新方法后,查询结果为:

这就实现了缓存数据一致了。

2.2 Canal + MQ解决存数据一致性问题

缓存与数据库的数据一致性问题,是分布式系统中一个常见且复杂的挑战。使用 Canal 和消息队列(MQ),是一种非常有效的方式来确保缓存与数据库之间的数据一致性。

2.2.1什么是Canal

Canal 是阿里巴巴开源的一个 MySQL binlog 增量订阅和消费组件。它可以模拟 MySQL 主从复制的过程,从而读取主库的 binlog,实时地监控和捕获数据变更。这样就可以将数据库的更新实时同步到其他系统或缓存中。

2.2.2什么是MQ

消息队列(MQ)是一种异步通信协议,允许系统之间通过队列传递消息。常见的 MQ 实现有 RabbitMQ、Kafka、ActiveMQ 等。MQ 可以用来实现数据的异步处理和分布式事务的协调。

流程概述:

1.Canal 监听数据库变更:

Canal 连接到 MySQL 数据库,模拟从库,订阅 binlog 日志,实时捕获数据库的增、删、改操作。

2.Canal 将变更数据推送到 MQ:

捕获到的数据库变更事件(如 insert、update、delete)被 Canal 推送到消息队列中。

3.消费 MQ 消息并更新缓存:

一个消费者(或者多个消费者)订阅 MQ 的消息,获取到变更事件后,根据事件的类型和内容,更新缓存中的对应数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值