Redis的旁路缓存策略和先删除缓存后更新数据库,先更新数据库后删除缓存,这三种策略之间有什么关系??

文章目录

      • [1. 旁路缓存策略 (Cache Aside Pattern) ------ 总体架构](#1. 旁路缓存策略 (Cache Aside Pattern) —— 总体架构)
      • [2. 三者的逻辑演进与竞争态分析](#2. 三者的逻辑演进与竞争态分析)
        • [A. 先删除缓存,后更新数据库](#A. 先删除缓存,后更新数据库)
        • [B. 先更新数据库,后删除缓存(Cache Aside 标准做法)](#B. 先更新数据库,后删除缓存(Cache Aside 标准做法))
      • [3. 三种策略的关系总结表](#3. 三种策略的关系总结表)
      • [💡 深度思考:为什么是"删除"而不是"更新"缓存?](#💡 深度思考:为什么是“删除”而不是“更新”缓存?)

这是一个非常经典且高频的后端面试/实战问题。简单来说,它们之间的关系是: "旁路缓存(Cache Aside)"是一个宏观的架构模式,而另外两者是实现该模式中"更新操作"的具体时序方案。

作为后端开发者,你可以把它们看作是"抽象接口"与"具体实现"的关系。


1. 旁路缓存策略 (Cache Aside Pattern) ------ 总体架构

这是目前互联网最通用的缓存模式。它的核心逻辑分为两部分:

  • 读请求: 先读缓存,缓存命中则返回;缓存失效则读数据库,然后将数据写回缓存。
  • 写请求(关键点): 先更新数据库,然后让缓存失效(删除缓存)。

它们的联系就在这里: 当我们要执行"写请求"时,究竟是"先删缓存后更新数据库"还是"先更新数据库后删除缓存",这就是你提到的另外两种具体策略。


2. 三者的逻辑演进与竞争态分析

为了保证数据库(Source of Truth)和缓存的一致性,我们需要分析在并发环境下,这两种时序会发生什么。

A. 先删除缓存,后更新数据库

这种方案在并发环境下非常脆弱,容易产生永久性脏数据

  1. 线程 A 执行写操作,先删除了缓存
  2. 此时线程 B 执行读操作,发现缓存缺失,去读数据库(旧值)
  3. 线程 B 将旧值写入缓存
  4. 线程 A 更新数据库(新值)
  • 结果: 缓存里永远是旧值,数据库里是新值。除非缓存过期,否则不一致会一直持续。
  • 修复方案: 采用"延时双删"策略(在更新完 DB 后,sleep 一段时间再删一次缓存)。
B. 先更新数据库,后删除缓存(Cache Aside 标准做法)

这是业界最推荐的方案,虽然理论上仍有极其微小的概率出现不一致,但概率极低。

  1. 线程 A 执行读操作,缓存刚好失效,读数据库(旧值)
  2. 线程 B 执行写操作,更新数据库(新值) ,然后删除缓存
  3. 线程 A 将此前读到的旧值写入缓存
  • 结果: 产生脏数据。
  • 为什么概率低? 因为步骤 3(写缓存)的速度远快于步骤 2(更新 DB),通常读线程会在写线程删除缓存前就完成写入。
  • 修复方案: 配合消息队列(MQ)进行重试删除,确保缓存最终一定被删掉。

3. 三种策略的关系总结表

维度 旁路缓存 (Cache Aside) 先删缓存,后更库 先更库,后删缓存
层级关系 架构模式(顶层设计) 写操作的具体实现方案 A 写操作的具体实现方案 B
核心目的 保证 DB 与 Cache 最终一致 试图通过先清理缓存来强制触发加载 默认方案,降低并发冲突概率
并发风险 取决于写操作的时序 极高(容易产生永久脏数据) 极低(仅在读快于写时发生)
典型补救 无(需结合具体方案) 延时双删 MQ 异步重试删除

💡 深度思考:为什么是"删除"而不是"更新"缓存?

在 Cache Aside 模式中,无论是 A 还是 B 策略,大家通常都选择删除缓存 (Delete),而不是更新缓存(Update)。原因有二:

  1. 性能开销: 如果缓存的数据是经过复杂计算得到的(比如多次 Join),每更一次库就更新一次缓存,代价太大。采用"懒加载"更合适。
  2. 并发安全: 如果两个写线程并发更新缓存,可能出现 DB 是新值,但缓存被旧的写请求覆盖的情况(类似丢失更新)。

总结建议:

在你的 Java 后端开发实践中(比如你之前提到的《小哈书》微服务项目),直接采用 "先更新数据库,后删除缓存" 即可。如果对一致性要求极高,可以引入 Canal 监听 MySQL binlog 来异步删除 Redis 缓存,这样可以解耦业务代码并解决删除失败的问题。

你目前的项目里,是否有遇到因为高并发导致的缓存不一致现象?如果有,我们可以针对具体的业务场景(比如点赞数、评论列表)聊聊更细化的处理手段。

相关推荐
我爱cope3 小时前
【Agent智能体4 | 智能体AI的应用】
数据库·人工智能·职场和发展
知识分享小能手4 小时前
Flask入门学习教程,从入门到精通,数据库操作 — 知识点详解与案例代码(4)
数据库·学习·flask
我是一颗柠檬4 小时前
【MySQL全面教学】MySQL基础SQL语句Day3(2026年)
数据库·后端·sql·mysql·oracle
XS0301064 小时前
MyBatis动态SQL
数据库·sql·mybatis
MandalaO_O4 小时前
MyBatis 与 MySQL 执行流程
数据库·mysql·mybatis
Donk_675 小时前
ELK+Redis架构搭建
redis·elk·架构
l1t5 小时前
DeepSeek总结的将 Rust Delta Kernel 集成到 ClickHouse
数据库·clickhouse·rust
qq_283720055 小时前
万字深度:Chroma 向量数据库全解析 — 核心原理、实战操作、性能优化与工程最佳实践
数据库·性能优化
黄筱筱筱筱筱筱筱6 小时前
二进制包安装MySql服务
数据库