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

数据库与缓存数据一致性的全部方案

背景

工作中我们经常会有以下的场景

(1)先查缓存,缓存有数据就直接返回

(2)缓存没数据就查数据库,数据库有数据返回,并且将数据写入缓存

(3)数据库也没有数据就返回空

 如果只是简单的查询和新增倒是可以,但是如果涉及更新删除这个流程存在两个问题

(1)如果需要更新缓存中的数据和更新数据库中的数据任意一个更新失败,会导致缓存中存在错误的数据

(2)如果任意一个删除失败会导致缓存中存在脏数据

本文将详细讲解下几种经典保证数据库和缓存一致性的方案

一、先更新数据库,再删除缓存

这是 最常用、最经典的缓存模式,也被叫做 旁路缓存模式(Cache-Aside)

流程:

写请求:
[客户端] → 更新 DB → 删除缓存 → 返回读请求:
[客户端] → 查缓存?↳ 有 → 返回↳ 无 → 查 DB → 写入缓存 → 返回

✅ 优点:

  • 简单易懂,广泛使用(Redis 官方推荐)
  • 缓存只保存热点数据,节省内存

❌ 缺点 & 风险:

问题场景
缓存未删除成功删除失败 → 下次读取仍返回旧值
并发写导致脏读A 更新 DB → B 查询(旧缓存)→ A 删除缓存失败 → 脏数据
缓存穿透查不到的数据反复查 DB

🛡️ 改进措施:

  • 删除失败重试(最多几次)
  • 给缓存设置合理过期时间(兜底)
  • 使用消息队列异步删除(见后文)

二、延迟双删

针对“先更新 DB 后删缓存”可能存在的 并发问题 提出的优化。

问题场景:

T1: 线程A 更新 DB(新值)
T2: 线程B 查询缓存(命中旧值) ← 危险! 
T3: 线程A 删除缓存 → 用户读到了旧数据

解决方案:

在更新前后各删一次缓存

✅ 作用:

  • 第一次删:防止后续请求命中旧缓存
  • 延迟:让可能正在执行的读请求完成
  • 第二次删:清理在这期间被重建的旧缓存

缺点:

  • sleep 影响性能
  • 时间不好控制(太短无效,太长卡顿)
  • 不能彻底解决问题

仅作为临时缓解手段,不推荐线上长期使用

三、基于消息队列的异步更新(异步解耦)

用 MQ 解耦“更新 DB”和“删除缓存”,实现可靠最终一致性。

流程:

[应用] → 更新 DB → 发送 MQ 消息(user:update:1)↓[消费者] → 删除缓存

✅ 优点:

  • 删除失败可重试(MQ 保障可达性)
  • 解耦业务逻辑与缓存操作
  • 可支持多级缓存同步

❌ 缺点:

  • 引入 MQ,系统复杂度上升
  • 存在一定延迟(最终一致性)
  • 需处理消息幂等性

🎯 适用场景:

  • 对一致性要求较高但允许短暂延迟
  • 已有 MQ 基础设施(如 RocketMQ、Kafka)

四:监听数据库日志(Canal / Debezium)

流程:

  1. 应用更新 DB
  2. Canal 捕获 binlog 变更
  3. 解析出 table、pk、type(insert/update/delete)
  4. 自动删除对应缓存 key

✅ 优点:

  • 完全解耦应用与缓存
  • 即使应用崩溃也能保证缓存更新
  • 支持跨语言、多消费端

❌ 缺点:

  • 运维成本高(需部署 Canal 集群)
  • 延迟略高(ms ~ s 级别)
  • 需要维护 key 映射规则(如 user:1 → user表 pk=1)

🎯 适用场景:

  • 大型互联网公司(阿里、滴滴等广泛使用)
  • 多个服务共用同一数据库
  • 要求高可靠性、低侵入性

五、Read/Write Through 模式(封装缓存层)

将缓存操作封装在一个“缓存服务”中,对外提供统一接口。

流程:

Write-Through(写穿透):

写请求 → 缓存层 → 缓存层同时更新 DB → 返回

Read-Through(读穿透):

读请求 → 缓存层 → 若无,则自动加载 DB 并写入缓存

✅ 优点:

  • 对调用方透明
  • 易于统一管理重试、降级、监控

❌ 缺点:

  • 必须确保缓存层高可用(否则成单点)
  • 写操作变慢(必须等 DB 完成)
  • 实现复杂(需处理失败回滚)

📌 更适合做中间件(如自研缓存平台),不适合普通项目。

五种方案总结:

方案一致性复杂度性能推荐指数适用场景
1. 先更新 DB 再删缓存中(最终)⭐⭐⭐⭐⭐⭐⭐⭐⭐☆通用推荐
2. 延迟双删⭐⭐⭐⭐⭐⭐不推荐
3. 消息队列异步删除高(可靠)⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐☆已有 MQ 的中大型系统
4. Binlog 监听(Canal)很高⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐☆大厂、高可靠性要求
5. Write-Through⭐⭐⭐⭐⭐⭐⭐⭐⭐自研缓存平台

生产环境选型建议

团队规模推荐方案
初创公司 / 小团队✅ 方案1 + 设置 TTL + 空值缓存
中型项目 / 已有 MQ✅ 方案1 + MQ 异步删除(失败重试)
大型互联网公司✅ Binlog 监听 + 缓存自动失效
高一致性要求✅ Binlog 监听 或 MQ + 分布式锁 + 监控告警
http://www.dtcms.com/a/449344.html

相关文章:

  • 算命公司网站建设制作开发方案网站商城怎么做app
  • 遗传算法解决TSP问题
  • MVC的含义
  • DBSCAN 密度聚类算法
  • 【极客日常】用Eino+Ollama低成本研发LLM的Agent
  • 《深入 Django ORM:select_related 与 prefetch_related 的实战剖析与性能优化指南》
  • 男科医院网站模板视频加字幕软件app
  • 网站开发自荐信江门专业网站制作费用
  • nat address-group 概念及题目
  • 深度学习模型构建的本质——“核心四要素+任务适配逻辑”
  • 基于SpringBoot+Vue的志行交通法规在线模拟考试(AI问答、WebSocket即时通讯、Echarts图形化分析、随机测评)
  • 厦门建网站费用一览表网站设计流行趋势
  • Docker Compose 搭建 LNMP 环境并部署 WordPress 论坛
  • 无锡企业网站制作哪家好前端的网站重构怎么做
  • TensorFlow2 Python深度学习 - 深度学习概述
  • Davor的北极探险资金筹集:数学建模与算法优化(洛谷P4956)
  • Web Components 的开发过程举例
  • 【Algorithm】Day-1
  • 提示工程深度解析:驾驭大语言模型的艺术与科学
  • 网站开发证书是什么中国建设学会查询网站
  • java代码随想录day50|图论理论基础
  • 【模型量化迁移】详解:让AI大模型在端侧“轻装上阵”的核心技术
  • 【Proteus仿真】虚拟终端出现乱码问题解决
  • 深入理解HarmonyOS ArkTS语法:从基础到高级应用开发
  • Photoshop - Photoshop 工具栏(5)多边套索工具
  • 做彩票网站空间去哪买网站主播
  • JavaWeb--Ajax
  • 网站建设与维护报告总结许昌网站建设汉狮套餐
  • [初学C语言]关于scanf和printf函数
  • Oracle OCP认证考试题目详解082系列第2题