【2025下半年系统架构设计师案例分析】电商平台 MySQL + Redis 与缓存击穿治理

文章目录

题目背景

某电商平台为提升系统性能,采用 MySQL 作为主数据库,同时引入 Redis 作为缓存存储热点数据。系统主要支持商品信息查询、库存管理及订单存储等业务:

业务 特点
商品详情 访问频繁,需快速响应
库存 需实时准确,支持高并发修改
订单 需长期保存,查询频率较低

数据分工:

  • Redis:热门商品基本信息(名称、价格等)、实时库存数量、热销商品排名等。
  • MySQL:完整商品数据、库存明细、订单全量信息及用户数据。

本题围绕热点数据在缓存失效时可能出现的 缓存击穿(热点 Key 失效瞬间大量请求直达数据库) ,分别考察 互斥锁方案(王工)逻辑过期方案(李工) 的流程填空与方案对比。


概念速记:缓存击穿

缓存击穿 :某个 Key 非常热点,在某一时刻被超高并发访问;当该 Key 失效的瞬间,持续的大并发"穿透"缓存直接请求数据库,导致数据库压力骤增甚至故障。

互斥锁思路 :缓存过期后,大量并发中只有 首个成功拿到锁 的线程去查库并回写缓存;其余线程 等待/重试,待缓存就绪后从缓存读取,从而避免同一热点多次打库。

逻辑过期思路 :在缓存值中附带 逻辑过期时间 ,物理上可不依赖 Redis TTL 立即删键;过期后 异步 从数据库刷新,期间仍可 先返回旧数据,以换取低延迟与高吞吐(容忍短暂不一致)。


题目 2.3.1【问题1】(6分)

针对热点数据可能发生的缓存失效问题,架构师 王工 提出基于 互斥锁 的缓存实现方案。请补充架构图(序列图「互斥锁」)中的空白 (1) ~ (6)

图意说明(线程1 / 线程2)

  • 线程1:缓存未命中后,作为成功拿到锁的线程,完成「查库 → 回写 → 释放锁」。
  • 线程2 :缓存未命中后,在循环内 抢锁失败则休眠再重试 ,直到缓存被线程1写好,最终 缓存命中

下列序列图按真题常见 左右两泳道(线程1 / 线程2) 绘制:左侧线程1 自顶向下完成「未命中 → 加锁 → 查库 → 回写 → 释锁」;右侧线程2 在 循环 内完成「未命中 → 抢锁失败 → 休眠重试」,退出循环后 缓存命中 。填空 (1)~(6) 与图中序号一致。为贴近试卷排版,不单独拉出 Redis/MySQL/锁对象泳道,访问缓存与数据库体现在步骤说明中。

读图说明: 时间线上线程1 与线程2 并发 进入;线程2 在循环中多次「失败 → 休眠 → 再查缓存」,直到线程1 写完缓存后某次查询 命中 跳出循环。若需在图中显式画出对 Redis/MySQL 的消息,可在备考时另画带 缓存/数据库 参与者的展开图;答卷填空以本题五步 + 线程2 循环三步为准。

参考答案(填空)

序号 内容
(1) 获取互斥锁成功
(2) 查询数据库
(3) 更新缓存
(4) 释放锁
(5) 获取互斥锁失败
(6) 休眠一会,重试

解析

缓存击穿场景中,互斥锁是常用手段:只有首个线程 在缓存失效后访问数据库并更新缓存,其他线程 暂停等待 ;首线程释放锁后,其余线程 直接从缓存读取,避免对数据库的并发冲击。


题目 2.3.2【问题2】(8分)

针对同类问题,架构师 李工 提出 逻辑过期 方案。请补充架构图(含「逻辑过期时间」、多线程协作)中的空白 (1) ~ (8)

参考答案(填空)

注:真题图中锁的表述可能写作「分布式锁」或「互斥锁」,语义一致:同一热点更新互斥即可。

序号 内容
(1) 获取分布式锁成功
(2) 开启新线程
(3) 返回旧数据
(4) 查询数据库
(5) 更新缓存
(6) 释放锁
(7) 获取分布式锁失败
(8) 返回旧数据

解析

逻辑过期通过在缓存数据中 额外存储逻辑过期时间 ;过期后 不立即删除缓存 ,而是 启动异步任务 从数据库加载最新数据并写回缓存;刷新期间 仍返回旧数据 ,避免请求阻塞。代价是可能出现 短时不一致

图意说明(典型三线程版本)

  • 线程1 :发现逻辑过期 → 加锁成功启动新线程(异步刷新)立即返回旧数据(不阻塞用户)。
  • 线程2(后台) :查库 → 更新缓存并重置逻辑过期时间释放锁
  • 线程3 :发现逻辑过期 → 加锁失败直接返回旧数据(与线程1抢锁失败时的处理一致,避免集体打库)。

完整流程还可包含 线程4 :逻辑时间已被线程2刷新后,缓存命中且未过期 ,返回新数据。图示常强调:不设置物理过期 / 逻辑过期高可用、性能好 ,但存在 短暂不一致


题目 2.3.3【问题3】(11分)

对比 王工(互斥锁方案)李工(逻辑过期方案) 各自的优缺点。

参考答案(要点)

互斥锁方案

优点:

  • 数据一致性高:同一时刻仅一个线程访问数据库并更新缓存,减少并发写缓存、读脏数据等问题,一致性较好。
  • 实现简单直观:过期后抢锁 → 查库 → 回写 → 释放,流程清晰。

缺点:

  • 线程阻塞 :持锁线程若查库/写缓存较慢,其他线程长时间等待,响应时间变差
  • 死锁风险 :异常路径若未释放锁,可能造成 死锁(需超时、finally、看门狗等治理)。
  • 性能问题 :高并发下大量线程阻塞等待锁,吞吐下降
逻辑过期方案

优点:

  • 非阻塞 :逻辑过期后仍可 立即返回(多为旧数据),请求不被长时间阻塞。
  • 性能好 :线程竞争与等待少,并发能力相对更强。

缺点:

  • 数据不一致 :刷新完成前用户可能读到 过期数据 ,难以保证强一致,多为 最终一致
  • 实现复杂 :需维护逻辑过期字段、异步刷新、锁与缓存更新的 原子性/协作,边界情况多。
  • 内存占用 :数据不随物理 TTL 立即淘汰时,可能 长期占内存,需额外淘汰或容量策略。

解析(综合)

互斥锁与逻辑过期都是应对 缓存击穿 的常见策略。

  1. 互斥锁 :缓存失效(未命中)时,首个请求线程尝试获取互斥锁;成功则查库、更新缓存并释放锁,失败则 等待 直至锁释放。通过 串行化数据库访问 保证一致性,但高并发下大量线程等待会 增加延迟、降低吞吐 ,更适合 一致性要求极高、并发相对可控 的场景。

  2. 逻辑过期 :缓存"过期"后仍可先 返回旧数据 ,同时 异步 查库更新;不阻塞主流程,并发能力与体验 更好,但存在 短暂不一致 ,更适合 高并发、可容忍短时不一致 的业务(如电商展示、资讯类读多写少场景)。


考点小结

  • 缓存击穿缓存雪崩缓存穿透 的区别(本题侧重热点 Key 失效瞬间)。
  • 互斥锁 :强一致、实现简单,代价是 阻塞与锁治理
  • 逻辑过期 :高可用、低延迟,代价是 一致性减弱与工程复杂度
相关推荐
CinzWS2 小时前
中断向量表中断号与 CMSIS IRQn 映射关系深度剖析:从硬件索引到软件句柄的桥梁
arm开发·架构·系统架构·嵌入式·cortex-m3·中断
艾莉丝努力练剑2 小时前
【MYSQL】MYSQL学习的一大重点:表的约束
linux·运维·服务器·开发语言·数据库·学习·mysql
祭曦念3 小时前
MySQL基础运维:日志基础之慢查询日志与错误日志 | 作用、配置与查看方法全实战
运维·mysql·adb
FL4m3Y4n3 小时前
MySQL事务原理分析
数据库·mysql
入瘾3 小时前
Redis 服务启动失败
数据库·redis·缓存
菱玖3 小时前
常用的SQL语句(MySQL运行)
数据库·mysql
roman_日积跬步-终至千里3 小时前
【系统架构设计师】2025下半年 · 系统架构设计师论文题目与考试分析
系统架构
cyforkk4 小时前
分布式缓存一致性:从核心争议到企业级解决方案
缓存
秋94 小时前
windows中下载并部署mysql-8.0.44-winx64详细过程
windows·mysql·adb