当前位置: 首页 > news >正文

缓存与数据库一致性:从问题到解决方案全解析

一、⼀致性问题的由来:为什么会不一致?

我们先从现实例子出发,来看为什么会出现一致性问题:

📦 场景举例:电商下单业务

  1. 用户提交订单 → 服务写入数据库订单表;
  2. 同时更新缓存(比如用户的订单数量缓存);
  3. 如果在更新缓存前服务宕机了,那么缓存没有更新;
  4. 数据库是最新的,缓存却是旧的。

这个时候就出现了“缓存与数据库数据不一致”的问题。


二、可能出现不一致的典型操作顺序

操作顺序描述风险
✅ 正常流程先更新数据库,再删除缓存
❌ 反向顺序先删除缓存,再更新数据库如果更新慢或失败,可能被其他请求重新写入旧缓存
❌ 异步删除缓存更新数据库后异步删除缓存异步失败就不会删掉缓存了
❌ 多线程并发写请求并发,缓存与数据库互不协调脏数据风险高

三、解决方案详解

✅ 方案 1:先更新数据库,再删除缓存(强一致)

这是大多数系统采用的方式:

1. update DB
2. delete cache

目前最流行的缓存读写策略 Cache Aside Pattern(旁路缓存模式)就是采用的先写数据库,再删缓存的方式。

  • 失效:应用程序先从缓存读取数据,如果数据不存在,再从数据库中读取数据,成功后,放入缓存。
  • 命中:应用程序从缓存读取数据,如果数据存在,直接返回。
  • 更新:先把数据写入数据库,成功后,再让缓存失效。

左耳朵耗子:Cache Aside Pattern

优点:只要删除成功,下一次读请求就会重新回源数据库拿到最新值再写入缓存。

缺点:并发高时,如果删缓存和数据库之间被另一个请求读到了旧缓存,就不一致。


✅ 方案 2:延迟双删策略(推荐)

为了防止缓存刚删完就被其他线程重新写回老数据,可以在第一次删缓存后等待一段时间再次删一次:

updateDB();
deleteCache();
Thread.sleep(500);
deleteCache();

在这里插入图片描述

适用于读多写少的场景,第二次延迟删除是为了避免“击穿后写入旧数据”。


✅ 方案 3:消息队列补偿策略(最终一致性)

流程如下:

1. 更新数据库成功后,发送一条消息到 MQ(如 Kafka、RocketMQ)
2. 缓存服务订阅这个消息,接收到后再删除缓存

可以专门起一个服务(比如 Canal,阿里巴巴 MySQL binlog 增量订阅&消费组件)去监听 MySQL 的 binlog,获取需要操作的数据。在这里插入图片描述

然后用一个公共的服务获取订阅程序传来的信息,进行缓存删除。

三分恶面渣逆袭:数据库订阅+消息队列保证key被删除
这种方式虽然降低了对业务的侵入,但增加了整个系统的复杂度,适合分布式系统中异步解耦场景。

📌 要求 MQ 高可靠、要做消息幂等处理


✅ 方案 4:读写都走缓存(缓存作为主存)

比如电商秒杀场景,订单库存都缓存于 Redis,数据库作为持久化。

  • 所有写操作先写 Redis
  • 后台定时同步到 DB(MySQL)
  • 或使用 binlog 异步写入(如 Canal)

风险:系统崩溃前未同步的缓存可能丢失,适用于对一致性要求不极端高的场景。


四、附图:缓存与数据库一致性解决策略图

在这里插入图片描述


五、常见问题及应对策略

面试提问建议回答
如何保证缓存和数据库一致性?描述“先更新数据库,再删除缓存”的基本原则,提出“延迟双删”、“消息队列”等高级策略
如果缓存刚删完就被旧值写回了怎么办?回答“延迟双删”或“使用分布式锁防止并发更新”
缓存更新失败怎么办?回答“使用 MQ 补偿机制,做幂等重试”

相关文章:

  • 04-微服务 面试题-mk
  • 斐波那契数列 (Fibonacci Sequence) C++
  • 0.DockerCE起步之Linux相关【完善中】
  • 提示词 (Prompt)
  • 树上搜索 第32次CCF-CSP计算机软件能力认证
  • 激光院董事长龚赤坤到北京研发中心检查指导工作
  • 深入解析 Spring AI ChatClient:构建高效 AI 应用的终极指南
  • 2025年3月 Scratch图形化四级 真题解析 中国电子学会全国青少年软件编程等级考试
  • ida 使用记录
  • 基于javaweb的SpringBoot新闻视频发布推荐评论系统(源码+部署文档)
  • Windows系统Python多版本运行解决TensorFlow安装问题(附详细图文)
  • 【我的创作纪念日】
  • 使用MVC模式开发cocos游戏功能
  • 基于springboot餐饮连锁店管理系统
  • HTML — 浮动
  • 2-刷力扣问题记录
  • .py文件和.ipynb文件的区别:完整教程
  • 【安装配置教程】在linux使用nginx部署vue项目
  • 【玩泰山派】5、点灯,驱动led (使用python库操作)
  • GMSL 使用 GPIO Forward 功能实现 Frame Sync
  • api模式网站开发/深圳短视频seo教程
  • 做韩国网站/seo关键词分析表
  • 网站建设顾问站建/优化公司怎么优化网站的
  • wordpress如何设置隐藏链接地址/温州seo网站建设
  • 昆明工程建设信息网站/网站不收录怎么解决
  • 成都个人团队网站开发/全网关键词搜索