系统设计 013:高并发系统缓存:从原理到实践全解析

系统设计 013:高并发系统缓存:从原理到实践全解析

  • [Bilibili 同步视频](#Bilibili 同步视频)
  • [一、💡 缓存到底是什么?](#一、💡 缓存到底是什么?)
    • [1.1 缓存不一定只在内存里](#1.1 缓存不一定只在内存里)
    • [1.2 缓存无处不在](#1.2 缓存无处不在)
  • [二、⚡ 主流缓存中间件:Memcached vs Redis](#二、⚡ 主流缓存中间件:Memcached vs Redis)
  • [三、🧩 Cache vs Java HashMap:别再混淆了!](#三、🧩 Cache vs Java HashMap:别再混淆了!)
    • [3.1 核心区别](#3.1 核心区别)
  • [四、⌛ TTL:缓存的 "自动过期魔法"](#四、⌛ TTL:缓存的 “自动过期魔法”)
  • [五、🔧 实战:缓存 + 数据库 配合查询(读多写少系统)](#五、🔧 实战:缓存 + 数据库 配合查询(读多写少系统))
    • [5.1 查询流程(GetUser)](#5.1 查询流程(GetUser))
  • [六、⚠️ 大坑:缓存与数据库数据一致性](#六、⚠️ 大坑:缓存与数据库数据一致性)
    • [6.1 为什么不能加锁?](#6.1 为什么不能加锁?)
  • [七、✅ 业界最佳实践:先更新 DB,再删除 Cache](#七、✅ 业界最佳实践:先更新 DB,再删除 Cache)
    • [7.1 为什么这么选?](#7.1 为什么这么选?)
    • [7.2 最终兜底:TTL 自动修复](#7.2 最终兜底:TTL 自动修复)
  • [八、📌 缓存核心总结](#八、📌 缓存核心总结)

Bilibili 同步视频

系统设计 013:高并发系统缓存:从原理到实践全解析

在高并发、大流量的后端场景里,300K 读请求 如同潮水般涌来,如何让系统稳如泰山、响应如闪电?答案只有一个:Cache(缓存)。它是读多写少系统的性能神器,是后端工程师必须吃透的核心技术。今天,我们就从原理、选型、对比、实战到一致性难题,把缓存彻底讲透。


一、💡 缓存到底是什么?

缓存,本质是 "空间换时间" 的高速数据层。

把高频访问、极少变更的数据,放在访问速度更快的介质中,下次请求直接命中,无需再去慢速数据源拉取,大幅降低响应耗时与数据库压力。

它的核心结构非常直观:Key-Value 键值对 ,给定 Key,立即返回 Value,和 Java 中的 HashMap 逻辑高度相似,但能力远不止于此。

1.1 缓存不一定只在内存里

很多人有个误区:Cache = 内存 ?大错特错!

缓存是逻辑概念,和存储介质无关:

  • 内存:最快、最常用

  • 文件系统(File System):可做网络数据 / 大计算结果的缓存

  • CPU 硬件:L1/L2/L3 Cache,直接决定电脑运行速度

  • 浏览器前端:静态资源(JS/CSS/ 图片)本地缓存

1.2 缓存无处不在

  • 服务端:Redis、Memcached 集群

  • 客户端:浏览器缓存、APP 本地缓存

  • 硬件层:CPU Cache、磁盘 Cache

    只要有快慢数据层,就有缓存的用武之地。


二、⚡ 主流缓存中间件:Memcached vs Redis

面对高并发读请求,我们不会手写 HashMap 充当缓存,而是使用成熟的缓存软件,最经典的就是 MemcachedRedis

特性 Memcached Redis
存储位置 纯内存 内存 + 硬盘
持久化 ❌ 不支持 ✅ 支持(RDB/AOF)
断电数据 全部丢失 可恢复
功能 简单 Key-Value 数据结构丰富 + 过期 + 事务 + 集群

一句话总结

纯内存高速缓存选 Memcached;需要持久化、复杂数据结构、高可用,直接用 Redis。


三、🧩 Cache vs Java HashMap:别再混淆了!

缓存和 HashMap 逻辑相似,但完全不是一个层级

3.1 核心区别

  1. 定位不同
  • HashMap编程语言内的数据结构

  • Cache:独立运行的软件 / 系统,提供网络协议、跨机器访问

  1. 淘汰机制(核心差异)
  • HashMap:无上限塞数据,内存满直接 OOM

  • Cache :自带内存淘汰策略,自动清理冷数据

    • LRU:Least Recently Used(最近最少使用,面试高频)

    • LFU:Least Frequently Used(最不经常使用)

  1. TTL 过期能力
    缓存支持 TTL(Time To Live) :给数据设置存活时间,到期自动删除。
    这是 HashMap 完全不具备的关键能力。

四、⌛ TTL:缓存的 "自动过期魔法"

python 复制代码
# 伪代码:设置带TTL的缓存
# key: user:1001,value: 用户数据,过期时间: 60秒
cache.set("user:1001", user_data, 60)

TTL = 数据的生命周期

60 秒后无论如何,缓存自动失效,下次请求必须回源数据库查询。

它不仅能控制内存占用,更是解决数据不一致的终极兜底方案


五、🔧 实战:缓存 + 数据库 配合查询(读多写少系统)

用户信息查询为例,这是最经典的缓存使用场景:

5.1 查询流程(GetUser)

python 复制代码
def get_user(user_id):
    # 1. 先查缓存
    key = f"user:{user_id}"
    user = cache.get(key)
    
    # 2. 缓存命中,直接返回
    if user is not None:
        return user
    
    # 3. 缓存未命中,查数据库
    user = db.query("SELECT * FROM user WHERE id = %s", user_id)
    
    # 4. 写入缓存,下次直接命中
    cache.set(key, user, 86400)  # 1天过期
    return user

✅ 逻辑和算法中的记忆化搜索(Memorization) 完全一致:

算过 / 查过的值,存起来直接复用,避免重复计算 / 查询。


六、⚠️ 大坑:缓存与数据库数据一致性

更新用户数据时,缓存和数据库如何同步?

常见 4 种写法:

  1. 先更新缓存,再更新数据库

  2. 先更新数据库,再更新缓存

  3. 先删缓存,再更新数据库

  4. 先更新数据库,再删缓存

结论:这 4 种全都不完美!

因为网络不可靠、操作可能失败、多线程并发抢占,会导致:

  • 缓存存旧数据

  • 数据库存新数据

    → 出现脏数据,业务逻辑错乱。

6.1 为什么不能加锁?

  • 缓存、数据库是两套独立系统

  • 本地锁(Mutex)只在单进程有效

  • 分布式锁(ZooKeeper/Redis)严重降低性能

缓存的初衷是提速,加锁等于本末倒置!


七、✅ 业界最佳实践:先更新 DB,再删除 Cache

虽然仍有极低概率不一致,但在 "读多写少" 系统中,概率几乎可忽略

7.1 为什么这么选?

  • 用户系统缓存命中率 ≥ 98%

  • Cache Miss 本身极少

  • 并发更新与查询 "刚好重叠" 的概率极低

7.2 最终兜底:TTL 自动修复

即便出现短暂不一致,只要给缓存设置 TTL

  • 到期自动失效

  • 下次查询重新从数据库加载最新数据

    最终一致性,完美兜底!


八、📌 缓存核心总结

  1. 缓存是读多写少系统的性能天花板,扛住高并发全靠它

  2. Key-Value 结构 ,支持淘汰算法 + TTL 过期

  3. Redis > Memcached(大多数业务场景)

  4. 缓存≠HashMap,一个是系统,一个是数据结构

  5. 更新策略:先 DB,后 Cache Delete

  6. 一致性兜底:TTL 自动过期


只要用好缓存,你的系统就能轻松扛住 百万级 QPS ,响应时间从百毫秒压到毫秒级。这是后端开发的必修课 ,更是面试与实战的必考点

相关推荐
暴躁小师兄数据学院10 小时前
【AI大模型应用开发工程师特训笔记】第04讲(第五章):条件判断与流程控制
大数据·人工智能·python·学习
Java 码思客10 小时前
【Spring AI实战】第2章 大模型基础调用:同步/异步/流式输出
java·人工智能·spring·ai
欧米欧10 小时前
C++进阶之AVL树
java·服务器·c++
学困昇10 小时前
Linux 信号机制详解:从 Ctrl+C 到 SIGCHLD,一文理解进程信号
linux·c语言·开发语言·人工智能·面试
我是一只码蚁10 小时前
记一次苍穹外卖项目 Maven 编译报错的排查与解决全过程
java·经验分享·笔记·后端·架构·maven
i220818 Faiz Ul10 小时前
理财系统|基于java+vue的家庭理财系统小程序(源码+数据库+文档)
java·vue.js·spring boot·小程序·论文·毕设·理财系统
深念Y10 小时前
DeepSeek/MiMo 推理链缓存代理:从内存到 SQLite 的两级缓存架构实战
数据库·缓存·架构·sqlite·内存·优化·分层
sichuanwww10 小时前
函数缓存lru_cache
缓存·函数缓存·lru_cache
半壶清水10 小时前
用 Python 和 OpenCV 提取书法作品中的每一个单字
python·opencv·计算机视觉