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

缓存和数据库一致性

在引入 Redis 缓存后,如何保证缓存和数据库(如 MySQL)的数据一致,是后端开发中最经典也最棘手的问题之一。

因为缓存和数据库是两套完全独立的存储系统,无法实现原生的跨系统分布式事务。在高并发下,只要读写请求的时序稍微错位,就可能导致两边数据不一致。

工业界通常不追求绝对的“强一致性”(因为会严重牺牲性能),而是追求“最终一致性”,即允许数据在极短的时间窗口内不一致,但能保证经过有限时间后,两边数据最终是对齐的。

下面为你拆解最主流的解决方案以及进阶的兜底策略:

🥇 行业标准方案:旁路缓存模式(Cache Aside Pattern)

这是目前 90% 以上互联网业务首选的方案,核心逻辑非常简单,分为读和写两个流程:

  • 读流程(固定不变)
    1. 先查 Redis 缓存,如果命中,直接返回数据。
    2. 如果缓存未命中,再去查数据库。
    3. 将数据库查到的最新数据写入 Redis,并返回结果。
  • 写流程(核心争议点)
    先更新数据库,再删除缓存

❓ 为什么是“删除缓存”而不是“更新缓存”?

  1. 懒加载,避免写放大:如果频繁修改数据但没人读取,更新缓存就是浪费计算资源。删除缓存后,只有下次真正有读请求时,才会触发数据库查询并回填缓存。
  2. 维护成本低:如果缓存是复杂的聚合对象(例如包含用户信息、订单数、等级等),每次更新都需要重新计算所有字段,而直接删除则简单高效。

❓ 为什么是“先更新数据库”而不是“先删缓存”?
如果是“先删缓存,再更新数据库”,在数据库还没更新完的间隙,如果有一个读请求进来,发现缓存没了,就会去数据库查到旧数据并回填到缓存。紧接着数据库更新完成,此时缓存里存的依然是旧数据,导致了长时间的脏数据。

⚠️ 标准方案的潜在风险与“延迟双删”

“先更新数据库,再删除缓存”虽然已经是最佳实践,但在极端并发或数据库主从架构下,依然存在极短的“不一致窗口”:
假设读请求在缓存失效的瞬间去查数据库,如果此时数据库主从同步有延迟,读请求可能从从库读到了旧值并回填到缓存。

为了缓解这个问题,衍生出了“延迟双删”策略:

  1. 先更新数据库。
  2. 删除一次缓存。
  3. 线程休眠一小段时间(例如 500ms)。
  4. 再次删除缓存。

第二次删除的目的,就是为了把“并发窗口期内,被其他读请求回填的旧缓存”再次清掉。

🛡️ 生产环境的终极兜底:Binlog 异步监听

“延迟双删”虽然有效,但休眠时间很难把控,且如果第二次删除因为网络抖动失败了怎么办?因此,在大型分布式系统中,通常会引入更可靠的兜底机制:监听数据库的 Binlog(变更日志)

核心流程:

  1. 业务代码只负责更新数据库,不再直接操作缓存(或者只负责第一次删除)。
  2. 引入中间件(如阿里的 CanalDebezium)伪装成 MySQL 的从库,实时订阅数据库的 Binlog。
  3. 当中间件监听到数据变更事件后,自动发送消息去删除或更新 Redis 中的对应缓存。

这种方案彻底解耦了业务代码和缓存逻辑,即使业务层删除缓存失败,Binlog 监听层也能保证最终把脏缓存清理掉。

📊 方案对比总结

为了让你更直观地选择,可以参考下表:

方案 一致性强度 实现复杂度 性能成本 适用场景
先更库后删缓存 最终一致性(绝大多数场景够用) 默认首选,90%的业务场景
延迟双删 最终一致性(比标准方案更可靠) 对一致性要求稍高,且能接受短暂延迟的场景
Binlog 异步监听 最终一致性(极高可靠性) 高(需维护中间件) 系统复杂、微服务众多、追求业务纯净的大型系统
分布式锁强一致 强一致性 极高(串行化) 金融核心交易、库存扣减等绝不容错场景

💡 避坑补充:防止缓存雪崩

在设置缓存过期时间时,千万不要给大批量的 Key 设置完全相同的过期时间(比如都设为凌晨 2 点过期)。一旦到达时间点,缓存集体失效,海量请求会瞬间击穿到数据库,导致数据库 CPU 飙升至 100% 甚至宕机(这就是缓存雪崩)。
最佳实践:在基础过期时间上,增加一个随机偏移量(例如基础 1 小时 + 随机 0~10 分钟),让缓存的失效时间均匀分散开。

http://www.jsqmd.com/news/766469/

相关文章:

  • 在VMware ESXi 7.0上给Ubuntu 18.04直通Tesla P100显卡,我踩了半年的坑终于填平了
  • autosub性能调优:如何提升语音识别准确率的10个实用技巧
  • TechXueXi终极指南:提升学习效率的10个实用技巧
  • [具身智能-597]:具身智能9步学习法:①机械本体 ②电机运动 ③传感/感知 ④仿真 ⑤数据与存储 ⑥规划/控制/模型/算法 ⑦学习/训练 ⑧仿真到现实 ⑨端云协同
  • Modern JavaScript Cheatsheet 容器化:Docker和Kubernetes部署终极指南
  • AI赋能开发:让快马平台智能优化你的7ku路7cc组件代码结构与性能
  • Canarytokens与Terraform集成:基础设施即代码安全监控的终极指南
  • 技术学习路线图制定终极指南:Awesome Learning Resources学习路径规划
  • 2026深度分析罗兰艺境B2B产业园招商GEO技术案例,测评苏锡常高新智谷优化过程与效果验证 - 罗兰艺境GEO
  • Rekall高级用法:如何编写自定义插件扩展取证功能
  • Nodejs后端服务调用Taotoken聚合API实现智能客服回复
  • 别再手动轮询了!STM32 HAL库串口DMA空闲中断接收不定长数据,实战解析SBUS遥控器信号
  • 如何快速部署web3-react:从开发到生产的完整指南
  • 低膨胀合金厂商哪家好?UNS K93600低膨胀合金厂商联系方式 - 品牌2026
  • KISS-ICP实战部署指南:从开发环境到生产系统的完整流程
  • 别再死磕V1了!手把手教你用WPS Web Office V3 SDK快速集成(附Java Demo避坑指南)
  • 使用Taotoken CLI工具一键配置团队开发环境中的API密钥
  • 终极指南:免费高效的微信聊天记录导出工具完整使用方案
  • 终极LobeChat社区支持指南:从问题求助到资源获取的完整路径
  • Logdy安全部署:完整的生产环境配置指南和最佳实践
  • tinyraycaster核心技术解析:从零理解光线投射算法实现原理
  • VSCode 2026跨端调试能力全解密,从React Native热重载卡顿到Tauri桌面应用内存泄漏,9个高危场景真实复盘与修复checklist
  • TechXueXi自动化测试终极指南:如何实现45分/天的稳定运行验证
  • 保姆级教程:为你的Python爬虫/脚本配置requests连接池与超时,告别HTTPSConnectionPool警告
  • 如何用NW.js开发功能强大的截图工具:从基础到高级图像编辑的完整指南
  • 2026视频去水印软件排行榜:哪个好用?好用的去水印工具实测推荐 - 科技热点发布
  • [具身智能-598]:具身智能9步学习法:①机械本体 ②电机运动 ③传感/感知 ④仿真 ⑤数据与存储 ⑥规划/控制/模型/算法 ⑦学习/训练 ⑧仿真到现实 ⑨端云协同
  • 别急着扔!废旧硬盘的无刷电机,竟是学习FOC算法的绝佳实验平台
  • 终极指南:如何用fastai实现半监督学习,有限标注数据也能训练高效模型
  • Cursor远程开发环境搭建:一键脚本解决服务器安装与Azure连接难题