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

mysql 与redis缓存一致性,延时双删 和先更新数据库,再删除缓存,哪个方案好

MySQL 与 Redis 缓存一致性方案比较:延时双删 vs 先更新数据库再删除缓存

在解决 MySQL 与 Redis 缓存一致性问题时,延时双删和先更新数据库再删除缓存是两种常见方案。下面我将从原理、优缺点、适用场景等方面进行详细对比。

1. 先更新数据库,再删除缓存(Cache-Aside 模式)

实现步骤

  1. 更新 MySQL 数据库

  2. 删除 Redis 缓存

  3. 后续查询会自动从数据库加载最新数据到缓存

优点

  • 实现简单:逻辑清晰直接

  • 性能较好:只有一次缓存删除操作

  • 减少不一致窗口:大多数情况下能保持较好一致性

缺点

  • 删除缓存失败:如果第二步失败会导致长期不一致

  • 短暂不一致窗口:在数据库更新后、缓存删除前可能有短暂不一致

代码示例

java

public void updateData(Data data) {// 1. 更新数据库dataDao.update(data);// 2. 删除缓存redisCache.delete(data.getId());
}

2. 延时双删策略

实现步骤

  1. 第一次删除 Redis 缓存

  2. 更新 MySQL 数据库

  3. 延时一段时间后再次删除 Redis 缓存

优点

  • 解决读写并发问题:能处理"读旧数据后写回缓存"的情况

  • 减少不一致时间:二次删除能捕获大多数不一致情况

缺点

  • 实现复杂:需要引入延时机制

  • 性能开销:两次删除操作

  • 延时难以确定:延时时间需要根据业务特点调整

代码示例

java

public void updateDataWithDoubleDelete(Data data) {// 1. 第一次删除缓存redisCache.delete(data.getId());// 2. 更新数据库dataDao.update(data);// 3. 延时再次删除缓存executor.schedule(() -> {redisCache.delete(data.getId());}, 500, TimeUnit.MILLISECONDS); // 通常延时500ms-1s
}

方案对比

比较维度先更新DB再删除缓存延时双删
实现复杂度简单较复杂(需要延时机制)
性能较好(1次删除)稍差(2次删除+延时)
一致性保证较好更好(解决更多边界情况)
失败影响可能导致长期不一致第一次失败同左,第二次失败影响小
适用场景一般业务场景对一致性要求高的场景

最佳实践建议

  1. 大多数场景:优先使用"先更新数据库,再删除缓存"方案

    • 实现简单

    • 性能更好

    • 配合重试机制和监控可以解决大多数问题

  2. 高并发敏感场景:考虑延时双删

    • 当存在大量读写并发时

    • 对一致性要求极高的场景(如金融核心业务)

  3. 增强措施(两种方案都适用):

    • 引入消息队列:通过消息队列保证删除操作最终执行

    • 设置缓存过期时间:作为最后保障

    • 实现删除重试机制:应对网络抖动等问题

    • 监控告警:对缓存不一致情况进行监控

  4. 特殊考虑

    • 如果缓存数据计算成本很高,可以考虑"更新数据库+更新缓存"(但要注意并发写问题)

    • 对于极其关键的数据,可以考虑使用分布式锁

结论

对于大多数应用场景,"先更新数据库,再删除缓存"是更优选择,因为它在保证较好一致性的同时具有更简单的实现和更好的性能。只有在极高并发、对一致性要求极高的特殊场景下,才需要考虑使用延时双删策略。无论选择哪种方案,都应该配合重试机制、监控告警和适当的缓存过期策略来构建健壮的缓存系统。

http://www.lryc.cn/news/587935.html

相关文章:

  • 深浅拷贝以及函数缓存
  • 机床自动化中的“方言翻译官”:EtherNet/IP 转 PROFIBUS DP 实战手记
  • Redis作缓存时存在的问题及其解决方案
  • TensorFlow深度学习实战(26)——生成对抗网络详解与实现
  • 聚宽sql数据库传递
  • sqlserver迁移日志文件和数据文件
  • pytorch小记(二十九):深入解析 PyTorch 中的 `torch.clip`(及其别名 `torch.clamp`)
  • linux 驱动的platform机制:
  • SQL ORM映射框架深度剖析:从原理到实战优化
  • SPL 轻量级多源混算实践
  • Redis集群方案——Redis分片集群
  • Linux 消息队列接收与处理线程实现
  • python的微竞网咖管理系统
  • P2802 回家
  • 国家互联网信息办公室关于发布第十二批深度合成服务算法备案信息的公告
  • 力扣算法--数青蛙与外观数列问题
  • 3.2 WPF 画散点图
  • 【Python3教程】Python3高级篇之MySQL - mysql-connector 驱动介绍及示例
  • 【WPF】WPF 自定义控件 实战详解,含命令实现
  • 深地之下的智慧触角:Deepoc具身智能如何为矿业机器人铸就“感知之核”
  • Mac (m1) Java 加载本地C共享库函数 .dylib 函数 Unable to load library ‘liblicense‘
  • 【爬虫】Python实现爬取京东商品信息(超详细)
  • 来时路,零帧起手到Oracle大师
  • FilterRegistationBean报错does not have type parameters。idea启动日志无明显报错提示冲突 kaki的博客
  • IDEA实现纯java项目并打包jar(不使用Maven,Spring)
  • Linux的相关学习
  • Oracle物化视图函数使用注意事项
  • Oracle 递归函数及 其他数据库 CTE 使用小计
  • SpringBoot集成SAP,本地IDEA启动和Windows服务器部署
  • 企业培训笔记:axios 发送 ajax 请求