当前位置: 代码网 > it编程>数据库>Redis > Redis和数据库双写一致性问题的解决方案

Redis和数据库双写一致性问题的解决方案

2025年08月06日 Redis 我要评论
下面我将详细解答redis与数据库双写一致性问题,结合故事举例说明,最后用思维导图总结核心解决方案。问题解答核心问题:当同时更新redis缓存和数据库时,由于网络延迟、操作顺序等问题导致数据不一致。解

下面我将详细解答redis与数据库双写一致性问题,结合故事举例说明,最后用思维导图总结核心解决方案。

问题解答

核心问题:当同时更新redis缓存和数据库时,由于网络延迟、操作顺序等问题导致数据不一致。

解决方案(含故事举例)

假设电商平台有商品库存系统:

// 商品服务类
public class productservice {
    private db db = new mysql();  // 数据库
    private cache cache = new redis();  // 缓存
}

1. 先更新数据库,再删除缓存(推荐方案)

public void updateproduct(product product) {
    db.update(product);          // 1. 更新数据库
    cache.delete(product.getid());// 2. 删除缓存
}

故事场景

管理员修改商品价格(100→80元):

  • 数据库先更新为80元 ✅
  • 删除redis中该商品的缓存

用户查询时:

  • 缓存未命中 → 读数据库(80元) ✅
  • 回填缓存(80元) ✅

优势

  • 避免"更新缓存失败导致永久不一致"
  • 缓存删除失败可重试(通过消息队列)

风险

并发时短暂不一致(概率低):

  • 用户a读缓存(空) → 读数据库(100元)
  • 管理员更新数据库(100→80) → 删缓存
  • 用户a写缓存(100元) ❌(旧数据)
  • 解决方案:延时双删(下文说明)

2. 延时双删策略

public void updatewithdelay(product product) {
    cache.delete(product.getid());    // 1. 先删缓存
    db.update(product);               // 2. 更新数据库
    thread.sleep(500);                // 3. 等待500ms
    cache.delete(product.getid());    // 4. 再删缓存
}

故事场景

解决上述并发问题:

  • 首次删除:清空旧缓存
  • 更新数据库 ✅
  • 等待期间可能写入的旧缓存被二次删除 ❌→✅

3. 监听数据库变更(最终一致性)

// 使用canal监听mysql binlog
canal.subscribe(event -> {
    if (event.isupdate()) {
        cache.delete(event.getkey()); // 异步删除缓存
    }
});

故事场景

订单系统库存变更:

  • 数据库减库存 ✅
  • canal捕获变更事件
  • 自动删除redis库存缓存
  • 下次查询回填最新值 ✅

4. 加分布式锁(强一致)

public void safeupdate(product product) {
    lock lock = redisson.getlock("product_" + product.getid());
    lock.lock();
    try {
        db.update(product);
        cache.update(product); // 同时更新缓存
    } finally {
        lock.unlock();
    }
}

适用场景

金融账户余额等强一致性要求:

  • 读写操作串行化
  • 性能较低(非高并发场景)

总结对比

方案一致性性能复杂度适用场景
先db后删缓存最终★★★★大部分业务
延时双删最终★★★高并发场景
监听binlog最终★★★★异构系统同步
分布式锁强一致★★金融/账户系统

核心原则

  • 优先保证数据库正确性
  • 缓存操作可失败/重试
  • 强一致性需牺牲性能

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com