0

0

mysql并发环境中缓存失效怎么办_mysql一致性方案

P粉602998670

P粉602998670

发布时间:2026-01-19 08:50:03

|

216人浏览过

|

来源于php中文网

原创

推荐方案是更新数据库后删除缓存并设过期时间兜底:先UPDATE MySQL,再DEL Redis,缓存必须EXPIRE(如EX 300),读miss时加updated_at校验,高一致场景直查库,优先用binlog监听(如canal)实现解耦、幂等的缓存清理。

mysql并发环境中缓存失效怎么办_mysql一致性方案

缓存失效时数据不一致的典型表现

在 MySQL + Redis 架构中,并发写入常导致「缓存未更新但数据库已变」,比如用户 A 更新订单状态为 paid,写库成功,删缓存也成功;但用户 B 几乎同时读缓存,拿到旧的 unpaid 状态——这不是缓存没删,而是删完之后、新值还没写入缓存前的窗口期被读到了脏数据。

先删缓存再更新数据库?不行,有竞态

看似合理的顺序,在并发下反而更危险:两个请求都走「删缓存 → 更新 DB」,第二个请求的 DB 写入完成后,缓存仍是空的,后续读请求会回源查到第二个请求写入的新值,然后写入缓存——这本身没问题;但若此时第一个请求的缓存重建(比如它带了延迟双删逻辑)把旧值又刷进去了,就彻底错乱。

  • DEL cache:order:123(请求 A)
  • UPDATE orders SET status='paid' WHERE id=123(请求 A)
  • DEL cache:order:123(请求 B)
  • UPDATE orders SET status='shipped' WHERE id=123(请求 B)
  • SET cache:order:123 {status:'paid'}(请求 A 的延迟重建,覆盖了正确的 shipped)

推荐方案:更新数据库后删除缓存 + 设置过期时间兜底

核心是放弃「强一致」幻想,接受短暂不一致,用「最终一致 + 降低风险」组合拳。关键点不在删缓存时机多精巧,而在如何让错误窗口更小、更可测。

  • 所有写操作统一走「先更新 MySQL,再 DEL 缓存」,不搞延迟双删
  • 缓存必须设 EXPIRE,比如 SET cache:order:123 {...} EX 300(5 分钟),避免永久脏数据
  • 读请求遇到缓存 miss,查库后写入缓存时,加一层「版本号 or 时间戳校验」:只当 DB 中的 updated_at 比缓存里记录的更新,才允许写入(需业务表有该字段)
  • 对一致性要求极高的场景(如支付单状态),读请求直接查库,绕过缓存——用开关控制,不是所有读都缓存
UPDATE orders 
SET status = 'paid', updated_at = NOW() 
WHERE id = 123 AND version = 5;

配合应用层检查返回影响行数是否为 1,失败则重试或告警。

沁言学术
沁言学术

你的论文写作AI助理,永久免费文献管理工具,认准沁言学术

下载

监听 binlog 做缓存更新比应用层更可靠

应用代码里删缓存容易漏(比如新增一个 DAO 方法但忘了配缓存清理),而 MySQL 的 binlog 是唯一真实写入源。用 canaldebezium 订阅变更,收到 UPDATE orders 事件后触发 DEL cache:order:${id},能消除应用层逻辑分散带来的不一致风险。

  • binlog 方案不依赖业务代码,改 SQL 就生效
  • 注意事务边界:一个事务含多条语句时,binlog 解析要按事务粒度投递,避免中间状态被消费
  • 消费端需幂等:同一条 binlog 可能重复投递,DEL 本身是幂等的,但如果是 SET 缓存就要加判断

真正难的不是选哪种方案,而是意识到「缓存永远比数据库慢半拍」,然后在业务可接受范围内,把这半拍控制在毫秒级、可监控、可降级。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

682

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

347

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

1095

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

357

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

676

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

575

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

417

2024.04.29

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

72

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 1.8万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 801人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号