# 缓存系统设计:从淘宝商品详情页看高性能架构
> 💡 **学习指南**:为什么用户点击淘宝商品详情页只需要 50 毫秒,而直接查数据库要 500 毫秒?这背后是一个精心设计的缓存架构在发挥作用。本章节将带你深入理解缓存的本质、模式与实战技巧。
---
## 0. 引言:为什么系统越来越慢?
### 0.1 一个真实的性能危机
2020 年双十一,某电商平台的数据库 CPU 使用率突然飙到 95%,订单查询响应时间从 100ms 暴涨到 8 秒。问题根源很快查明:一个新上线的促销页面,每次加载都要查询 50+ 次数据库,且没有缓存。
**核心问题暴露**——当流量激增时,数据库成为整个系统的瓶颈。
| 操作类型 | 响应时间 | 单节点 QPS | 瓶颈分析 |
| :------- | :------- | :--------- | :------- |
| L1 Cache 读取 | ~0.5 ns | 数十亿级 | CPU 内置,无瓶颈 |
| 内存读取 | ~100 ns | 百万级 | 内存带宽 |
| Redis 查询 | ~1 ms | 10万级 | 网络延迟 |
| MySQL 查询 | ~10 ms | 数千级 | 磁盘 IO |
| 跨机房查询 | ~100 ms | 百级 | 网络距离 |
**性能差距触目惊心**:内存操作比 MySQL 查询快 100,000 倍。
### 0.2 缓存的本质定义
缓存不是简单地把数据存到内存,而是一种**基于局部性原理的数据访问优化技术**。
**严格定义**:缓存是位于计算单元与慢速存储之间的高速数据存储层,通过存储最近或频繁访问数据的副本,减少访问延迟、提升系统吞吐量。
**与原始存储的核心区别**:
- 原始存储(数据库):容量大、持久化、查询慢
- 缓存:容量有限、易失性、查询极快
- 缓存内容永远是原始数据的**副本**,而非主数据
### 0.3 淘宝商品详情页的缓存实战
让我们拆解一个真实的电商商品详情页,看看缓存是如何层层发挥作用的。
**场景**:用户打开商品 ID 为 12345 的详情页。
**访问链路**(从上到下,层层穿透):
| 层级 | 存储位置 | 查询耗时 | 数据示例 | 命中率 |
| :--- | :------- | :------- | :------- | :----- |
| L1 | 浏览器本地缓存 | ~0ms | 静态图片、CSS、JS | 95%+ |
| L2 | CDN 边缘节点 | ~20ms | 商品主图、详情图 | 90%+ |
| L3 | Nginx 本地缓存 | ~1ms | 商品基础信息 JSON | 80%+ |
| L4 | 应用进程本地缓存 (Caffeine) | ~0.1ms | 热销商品详情 | 90%+ |
| L5 | Redis 集群 | ~2ms | 所有商品信息、库存 | 99%+ |
| L6 | MySQL 主从集群 | ~10ms | 全量商品数据 | 100% |
**最终效果**:
- 95% 的请求在前 4 层就被拦截,根本不会到达数据库
- 整体响应时间:P99 < 100ms
- 数据库 QPS 从理论上的 100万+ 下降到实际 5000 以下
---
## 1. 缓存的底层原理:局部性
缓存之所以有效,根植于计算机科学中一个被反复验证的观察:**局部性原理**。
### 1.1 时间局部性 (Temporal Locality)
**定义**:如果一个数据项被访问,那么在不久的将来它很可能再次被访问。
**技术解释**:程序在执行过程中,往往会对某些变量或数据对象进行反复读取或修改。这是因为:
- 循环结构会重复访问相同的计数器变量
- 函数调用会重复访问相同的参数和局部变量
- 热点数据(如用户会话、配置项)会被频繁查询
**实例**:用户登录后,系统需要反复查询该用户的权限信息。第一次查询后将结果缓存,后续几十次请求都可以直接从缓存获取,直到用户登出或权限变更。
### 1.2 空间局部性 (Spatial Locality)
**定义**:如果一个数据项被访问,那么与它地址相邻的数据项也很可能被访问。
**技术解释**:计算机存储和访问数据的方式天然具有连续性:
- 内存以缓存行(通常 64 字节)为单位加载数据
- 数组、列表等数据结构在内存中连续存储
- 磁盘读取以块(通常 4KB)为单位
- 业务数据往往按时间、分类等维度聚簇存储
**实例**:加载商品列表时,如果缓存了第 1-10 条商品数据,当用户翻页到第 11-20 条时,这些相邻的数据很可能已经被批量加载到缓存中,实现快速响应。
### 1.3 缓存的生命周期
一个缓存条目从创建到销毁,经历完整的生命周期:
```
写入 (Write) → 命中/未命中 (Hit/Miss) → 过期 (Expiration) → 淘汰 (Eviction)
```
**写入策略**:
- **主动写入**:系统启动时预加载热点数据(缓存预热)
- **懒加载**:首次访问时从数据库加载并写入缓存
- **异步更新**:后台线程定期刷新即将过期的数据
**过期策略**:
- **TTL (Time To Live)**:设置固定生存时间,到期自动失效
- **滑动过期**:每次访问后重置过期时间
- **绝对过期**:指定具体过期时间点
**淘汰策略**(缓存满时):
- **LRU (Least Recently Used)**:淘汰最近最少使用(最常用)
- **LFU (Least Frequently Used)**:淘汰访问频率最低
- **FIFO (First In First Out)**:先进先出
- **Random**:随机淘汰
---
## 2. 缓存架构选型
### 2.1 本地缓存 (Local Cache)
**定义**:与应用进程共享内存空间的缓存,无需网络访问。
**技术特点**:
- **访问延迟**:~100 纳秒(纯内存访问,无网络开销)
- **容量限制**:受限于单机内存(通常几百 MB 到几 GB)
- **一致性挑战**:多实例部署时,各节点缓存独立,数据可能不一致
- **进程绑定**:应用重启,缓存丢失
**主流实现**:
| 语言 | 库/框架 | 核心特性 |
| :--- | :------ | :------- |
| Java | Caffeine | 高性能,W-TinyLFU 淘汰算法,近乎完美的命中率 |
| Java | Guava Cache | 功能全面,但性能略逊于 Caffeine |
| Go | Ristretto | 高性能,高命中率,支持过期 |
| Go | BigCache | 专为大量 entry 设计,零 GC 压力 |
| Python | cachetools | 多种缓存策略,TTL 支持 |
### 2.2 分布式缓存 (Distributed Cache)
**定义**:作为独立服务部署的缓存系统,通过网络协议访问,多实例共享。
**技术特点**:
- **访问延迟**:~1-5 毫秒(网络开销)
- **容量扩展**:支持集群部署,容量可达数百 GB 甚至 TB
- **一致性保证**:所有应用实例访问同一份数据,天然一致
- **高可用**:支持主从复制、哨兵、集群模式
**主流实现对比**:
| 特性 | Redis | Memcached |
| :--- | :---- | :---------- |
| 数据结构 | String, Hash, List, Set, ZSet, Stream 等 | 仅 String |
| 持久化 | RDB, AOF 支持 | 不支持 |
| 集群 | Redis Cluster, Codis | 客户端分片 |
| 单线程/多线程 | 单线程(命令执行)| 多线程 |
| 内存管理 | 支持内存淘汰策略 | LRU 淘汰 |
| 适用场景 | 复杂数据结构、持久化需求 | 纯缓存、简单 KV |
### 2.3 多级缓存架构
在真实的生产环境中,单一缓存层往往无法满足性能和成本的双重需求。多级缓存架构通过在不同层级部署缓存,形成层层防护,最大化性能收益。
**典型多级缓存架构**:
```
┌─────────────────────────────────────────────────────────────────┐
│ 用户请求 │
└─────────────────────────┬───────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ L1: 浏览器缓存 (Browser Cache) │
│ - 存储:静态资源 (CSS/JS/图片) │
│ - 控制:Cache-Control, ETag, Last-Modified │
│ - 延迟:~0ms (本地磁盘/内存) │
└─────────────────────────┬───────────────────────────────────────┘
↓ (未命中)
┌─────────────────────────────────────────────────────────────────┐
│ L2: CDN 缓存 (Content Delivery Network) │
│ - 存储:静态资源、部分 API 响应 │
│ - 节点:全球分布,就近访问 │
│ - 延迟:~20-50ms │
└─────────────────────────┬───────────────────────────────────────┘
↓ (未命中)
┌─────────────────────────────────────────────────────────────────┐
│ L3: 反向代理缓存 (Nginx/Varnish) │
│ - 存储:完整 HTTP 响应、聚合数据 │
│ - 延迟:~1-5ms │
└─────────────────────────┬───────────────────────────────────────┘
↓ (未命中)
┌─────────────────────────────────────────────────────────────────┐
│ L4: 应用本地缓存 (Caffeine/Guava) │
│ - 存储:热点对象、配置、用户会话 │
│ - 延迟:~0.1ms │
└─────────────────────────┬───────────────────────────────────────┘
↓ (未命中)
┌─────────────────────────────────────────────────────────────────┐
│ L5: 分布式缓存 (Redis Cluster) │
│ - 存储:业务数据、会话、计算结果 │
│ - 延迟:~1-5ms │
└─────────────────────────┬───────────────────────────────────────┘
↓ (未命中)
┌─────────────────────────────────────────────────────────────────┐
│ L6: 数据库 (MySQL/PostgreSQL) │
│ - 存储:全量数据 │
│ - 延迟:~10-50ms │
└─────────────────────────────────────────────────────────────────┘
```
---
## 3. 缓存设计模式
当引入缓存层后,应用程序需要确定如何与缓存和数据库交互。业界形成了四种经典的设计模式,每种模式在一致性、性能和复杂度之间做出不同的权衡。
### 3.1 Cache-Aside (旁路缓存) — 最常用
**模式定义**:应用程序负责直接管理缓存,显式地从缓存读取、写入数据。缓存对数据库完全透明,不知道数据库的存在。
**读取流程**:
```
应用程序 ─┬─→ 查询缓存 ──→ 命中?─┬─是→ 返回数据
│ │
│ └─否→ 查询数据库
│ ↓
│ 写入缓存
│ ↓
└──────────────────────── 返回数据
```
**更新流程**(关键!):
```
应用程序 ──→ 更新数据库 ──→ 删除缓存(不是更新缓存!)
```
### 3.2 Read-Through (读穿透)
**模式定义**:应用程序只与缓存交互,缓存层负责在缺失时自动从数据库加载数据。对应用程序完全透明。
**工作原理**:
```
应用程序 ──→ 查询缓存 ──→ 未命中 ──→ 缓存服务自动加载数据库数据
↓
返回给应用
```
**优缺点对比**:
| 维度 | Read-Through | Cache-Aside |
| :--- | :----------- | :------------ |
| 代码复杂度 | 低(业务代码无缓存逻辑) | 中(显式管理缓存) |
| 灵活性 | 低(受限于缓存库实现) | 高(完全控制) |
| 首次加载延迟 | 较高(穿透到库) | 可控(可预热) |
| 适用场景 | 标准化缓存需求 | 复杂业务逻辑 |
### 3.3 Write-Through (写穿透)
**模式定义**:应用程序写入缓存,缓存服务同步将数据写入数据库,确保缓存和数据库强一致。
**工作原理**:
```
应用程序 ──→ 写入缓存 ──→ 缓存服务同步写入数据库 ──→ 返回成功
```
**特点**:
- **强一致性**:缓存和数据库始终一致
- **写入延迟高**:需等待数据库写入完成
- **吞吐量受限**:受限于数据库写入能力
**适用场景**:
- 对数据一致性要求极高的场景(金融交易、库存扣减)
- 写操作相对较少的场景
### 3.4 Write-Behind (异步写回)
**模式定义**:应用程序只写入缓存,缓存服务异步批量将数据写入数据库。
**工作原理**:
```
应用程序 ──→ 写入缓存(立即返回)
↓
后台异步批量写入数据库
```
**核心优势**:
- **写入极快**:~1ms 延迟,10万+ QPS
- **批量写入**:减少数据库 IO,提升吞吐量
- **削峰填谷**:将突发流量平滑化
**核心风险**:
- **数据丢失风险**:缓存宕机,未写入数据库的数据丢失
- **数据不一致窗口**:异步写入期间,缓存与数据库不一致
---
## 4. 缓存的三大经典问题
在实际生产环境中,缓存可能引入三类严重问题,需要系统性解决方案。
### 4.1 缓存穿透 (Cache Penetration)
**问题定义**:查询一个**不存在的数据**,缓存中没有(因为没有),数据库中也没有,导致每次请求都直接打到数据库。
**攻击场景**:
- 恶意攻击者构造大量不存在的 ID 进行查询(如 id=-1, id=999999999)
- 爬虫遍历不存在的资源路径
- 业务逻辑错误导致查询无效数据
**解决方案 1:布隆过滤器 (Bloom Filter)**
**原理**:在缓存之前加一层概率型数据结构,快速判断"这个 key **肯定不存在**或**可能存在**"。
**特性**:
- 100% 判断不存在(绝对不会误判为存在)
- 可能误判存在(实际不存在,但过滤器说可能存在,概率可调)
### 4.2 缓存击穿 (Cache Breakdown)
**问题定义**:某个**热点数据**在缓存中过期(TTL 到期),此时大量并发请求同时到达,都去查询数据库,导致数据库压力骤增。
**典型场景**:
- 微博热搜榜过期瞬间
- 明星八卦新闻缓存失效
- 秒杀活动开始时的库存数据
- 热门商品的缓存同时过期
**解决方案 1:互斥锁 (Mutex Lock)**
**原理**:当缓存失效时,只允许一个线程去查询数据库并重建缓存,其他线程等待或重试。
**解决方案 2:逻辑过期 (Logical Expiration)**
**原理**:不设置物理过期时间(TTL),而是在缓存 value 中嵌入逻辑过期时间字段。发现逻辑过期时,异步重建缓存,同时返回旧数据(永不过期)。
### 4.3 缓存雪崩 (Cache Avalanche)
**问题定义**:大量缓存数据在**同一时间点集中过期**(或 Redis 宕机),导致所有请求同时穿透到数据库,瞬间压垮数据库。
**典型触发场景**:
- 系统重启后,所有缓存从 0 开始重建,同时设置相同 TTL
- 定时任务批量刷新缓存,设置相同的过期时间
- 缓存服务(Redis)宕机或网络分区
- 大量热点数据同时达到过期时间
**解决方案 1:随机 TTL (Time To Live)**
**原理**:在基础过期时间上增加随机偏移量,打散过期时间点。
**解决方案 2:缓存预热 (Cache Preheating)**
**原理**:系统启动或定时任务主动将热点数据加载到缓存,避免冷启动时集中回源。
**解决方案 3:熔断降级 (Circuit Breaker)**
**原理**:当数据库压力过大时,暂时拒绝部分请求或返回降级数据,保护数据库不被压垮。
---
## 5. 缓存一致性策略
缓存的本质是数据的副本,副本与主数据(数据库)之间必然存在不一致的时间窗口。如何控制这个时间窗口,是缓存设计的核心挑战。
### 5.1 为什么不一致?
**并发写入场景**:
| 时间 | 线程 A(更新 age=25) | 线程 B(查询) | 数据库 | 缓存 |
| :--- | :-------------------- | :------------- | :----- | :--- |
| T1 | 更新 DB age=25 | - | 25 | 20(旧值) |
| T2 | - | 查询缓存(命中旧值) | 25 | 20 ❌ |
| T3 | 删除缓存 | - | 25 | - |
| T4 | - | - | 25 | 从 DB 加载 25 ✅ |
**问题**:在 T2 时刻,线程 B 读取到了缓存中的旧值 20,而此时数据库已经是 25。
### 5.2 最佳实践:先更新数据库,再删除缓存
**原理**:利用数据库的行锁机制,保证"更新"操作的排他性,最大限度减少不一致窗口。
**流程**:
```
写请求 ──→ 开启数据库事务 ──→ 更新数据库记录 ──→ 提交事务 ──→ 删除缓存
```
**为什么这个顺序最优?**
1. **数据库锁保护**:更新操作会获取行锁,其他读写操作必须等待,天然排他
2. **删除缓存是异步操作**:不需要等待缓存删除成功,数据库提交后即可返回
3. **极端情况仍可接受**:即使缓存删除失败,只是下次读取会回源,不会导致脏数据长期存在
### 5.3 延迟双删 (Delayed Double Deletion)
**场景**:先删缓存、再写 DB 的方案在极端并发下仍有不一致风险。延迟双删通过两次删除,最大限度保证一致性。
**流程**:
```
1. 删除缓存
2. 更新数据库
3. 等待一段时间(如 500ms)
4. 再次删除缓存
```
**三种一致性策略对比**:
| 策略 | 一致性级别 | 性能影响 | 复杂度 | 适用场景 |
| :--- | :--------- | :--------- | :------- | :------- |
| 先更新 DB,再删缓存 | 最终一致 | 低 | 低 | 大多数场景,推荐作为默认方案 |
| 延迟双删 | 强最终一致 | 中(延迟) | 中 | 对一致性要求较高的场景 |
| 先删缓存,再更新 DB | 弱 | 低 | 低 | 不推荐,易出现不一致 |
---
## 6. 实战:构建高性能缓存系统
### 6.1 场景分析:电商商品详情页
**业务特点**:
- 读多写少:100:1 的读写比
- 热点集中:20% 的商品贡献 80% 的流量
- 数据复杂度:商品基础信息 + 价格 + 库存 + 评价聚合
- 一致性要求:价格、库存强一致,其他可最终一致
**性能指标**:
- P99 响应时间 < 100ms
- 数据库 QPS 峰值 < 5000
- 缓存命中率 > 95%
### 6.2 架构设计
```
┌─────────────────────────────────────────────────────────┐
│ 客户端请求 │
└───────────────────────┬─────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ CDN 缓存层 │
│ - 商品主图、详情图 │
│ - Cache-Control: max-age=86400 │
└───────────────────────┬─────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Nginx 缓存层 │
│ - 商品基础信息聚合(包含价格、库存) │
│ - proxy_cache_valid 5m │
└───────────────────────┬─────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ 应用层 │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 本地缓存 │ │ 分布式锁 │ │
│ │ (Caffeine) │ │ (Redisson) │ │
│ │ - 热点商品 │ │ - 防击穿 │ │
│ │ - 配置信息 │ │ - 库存扣减 │ │
│ └─────────────────┘ └─────────────────┘ │
└───────────────────────┬─────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ Redis 集群 │
│ - 商品详情 Hash │
│ - 库存计数器 String │
│ - 热点商品列表 ZSet │
│ - 分布式锁 │
└───────────────────────┬─────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ MySQL 集群 │
│ - 商品主表 │
│ - 库存表(行锁控制并发) │
│ - 订单表 │
└─────────────────────────────────────────────────────────┘
```
### 6.3 核心代码实现
**完整的多级缓存实现(Java + Spring Boot)**:
```java
@Component
public class MultiLevelCache {
// 本地缓存:Caffeine
private final Cache localCache;
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private RedissonClient redissonClient;
// 缓存层级配置
private static final long LOCAL_TTL_SECONDS = 30;
private static final long REDIS_TTL_SECONDS = 300;
public MultiLevelCache() {
this.localCache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(Duration.ofSeconds(LOCAL_TTL_SECONDS))
.recordStats()
.build();
}
/**
* 多级缓存读取(L1: 本地缓存 -> L2: Redis -> L3: 数据库)
*/
public T get(String key, Class type, Supplier dbLoader) {
// L1: 本地缓存
Object localValue = localCache.getIfPresent(key);
if (localValue != null) {
return type.cast(localValue);
}
// L2: Redis 缓存(带分布式锁防击穿)
String redisKey = "cache:" + key;
String redisValue = redisTemplate.opsForValue().get(redisKey);
if (StrUtil.isNotBlank(redisValue)) {
T value = JSON.parseObject(redisValue, type);
// 回填本地缓存
localCache.put(key, value);
return value;
}
// L3: 数据库(带分布式锁)
String lockKey = "lock:" + key;
RLock lock = redissonClient.getLock(lockKey);
try {
boolean acquired = lock.tryLock(100, 10, TimeUnit.MILLISECONDS);
if (!acquired) {
// 获取锁失败,等待后重试
Thread.sleep(50);
return get(key, type, dbLoader);
}
// 双重检查
String doubleCheck = redisTemplate.opsForValue().get(redisKey);
if (StrUtil.isNotBlank(doubleCheck)) {
return JSON.parseObject(doubleCheck, type);
}
// 查询数据库
T value = dbLoader.get();
if (value != null) {
// 写入 Redis(带随机 TTL)
long ttl = REDIS_TTL_SECONDS + RandomUtil.randomInt(-30, 30);
redisTemplate.opsForValue().set(
redisKey,
JSON.toJSONString(value),
ttl,
TimeUnit.SECONDS
);
// 回填本地缓存
localCache.put(key, value);
}
return value;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("获取锁被中断", e);
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
/**
* 删除缓存(更新时调用)
*/
public void evict(String key) {
// 删除本地缓存
localCache.invalidate(key);
// 删除 Redis 缓存
redisTemplate.delete("cache:" + key);
}
}
```
---
## 7. 总结与学习路径
### 7.1 核心知识点回顾
| 知识点 | 关键概念 | 实战要点 |
| :----- | :------- | :------- |
| **局部性原理** | 时间局部性、空间局部性 | 根据访问模式设计缓存 key 和预热策略 |
| **多级缓存** | L1-L6 层级 | 浏览器 → CDN → Nginx → 本地 → Redis → DB |
| **缓存模式** | Cache-Aside、Read-Through、Write-Through、Write-Behind | Cache-Aside 最常用,Write-Behind 用于高并发写入 |
| **缓存穿透** | 查询不存在数据 | 布隆过滤器 + 缓存空对象 |
| **缓存击穿** | 热点数据过期 | 互斥锁 + 逻辑过期 |
| **缓存雪崩** | 大量数据同时过期 | 随机 TTL + 缓存预热 + 熔断降级 |
| **一致性策略** | 先更新 DB 再删缓存、延迟双删 | Cache-Aside + 延迟双删应对极端并发 |
### 7.2 学习路径建议
**阶段 1:理解原理(1-2 天)**
- 掌握局部性原理(时间、空间)
- 理解缓存生命周期(写入 → 命中 → 过期 → 淘汰)
- 了解不同存储介质的性能差异(CPU Cache → 内存 → SSD → HDD)
**阶段 2:掌握基础模式(2-3 天)**
- 实现 Cache-Aside 模式(读取、更新)
- 使用 Redis 做分布式缓存
- 理解为什么"更新时删除缓存而不是更新缓存"
**阶段 3:多级缓存实战(3-5 天)**
- 实现本地缓存(Caffeine/Guava)+ Redis 的两级架构
- 解决多级缓存的一致性问题
- 实现缓存统计和监控
**阶段 4:解决经典问题(1 周)**
- 缓存穿透:实现布隆过滤器
- 缓存击穿:实现互斥锁和逻辑过期
- 缓存雪崩:实现随机 TTL、缓存预热、熔断降级
**阶段 5:一致性保障(1-2 周)**
- 深入理解 Cache-Aside 模式的并发问题
- 实现延迟双删
- 了解 Binlog 订阅方案(Canal/Debezium)
**阶段 6:生产级实战(持续)**
- 设计完整的商品详情页缓存系统
- 搭建 Prometheus + Grafana 监控体系
- 进行压测验证和性能调优
### 7.3 推荐资源
**书籍**:
- 《Redis 设计与实现》(黄健宏)—— 深入理解 Redis 内部机制
- 《高性能 MySQL》(第 5 章:缓存策略)
**文章**:
- Martin Fowler: *Patterns of Distributed Systems*
- Redis 官方文档:https://redis.io/docs/
- Google: *Designing a Cache System*
**开源项目**:
- Caffeine(Java 本地缓存)
- Redisson(Java Redis 客户端,提供分布式锁等)
- JetCache(阿里开源的多级缓存框架)
---
## 8. 名词速查表 (Glossary)
| 名词 | 全称 | 解释 |
| :--- | :--- | :--- |
| **Cache** | - | **缓存**。存储数据副本的快速存储层,用于加速访问。 |
| **Hit** | - | **缓存命中**。请求的数据在缓存中找到,无需访问数据库。 |
| **Miss** | - | **缓存未命中**。请求的数据不在缓存中,需要回源查询。 |
| **Hit Ratio** | - | **命中率**。缓存命中的请求数占总请求数的比例(目标: > 95%)。 |
| **TTL** | Time To Live | **生存时间**。缓存条目的过期时间。 |
| **Eviction** | - | **淘汰**。缓存满了时,删除旧数据为新数据腾空间。 |
| **LRU** | Least Recently Used | **最近最少使用**。常见的缓存淘汰策略。 |
| **LFU** | Least Frequently Used | **最不经常使用**。按访问频率淘汰的策略。 |
| **Cache Penetration** | - | **缓存穿透**。查询不存在数据,导致请求直接打到数据库。 |
| **Cache Breakdown** | - | **缓存击穿**。热点数据过期,瞬间大量请求打到数据库。 |
| **Cache Avalanche** | - | **缓存雪崩**。大量缓存同时过期,数据库压力骤增。 |
| **Bloom Filter** | - | **布隆过滤器**。空间效率高的概率型数据结构,用于判断元素是否可能存在。 |
| **Cache-Aside** | - | **旁路缓存**。应用代码直接操作缓存和数据库的模式。 |
| **Read-Through** | - | **读穿透**。缓存库自动从数据库加载数据。 |
| **Write-Through** | - | **写穿透**。写入缓存时同步写入数据库。 |
| **Write-Behind** | - | **异步写回**。写入缓存后异步批量写数据库。 |
| **Local Cache** | - | **本地缓存**。与应用在同一进程内的缓存(如 Caffeine)。 |
| **Distributed Cache** | - | **分布式缓存**。独立服务,通过网络访问(如 Redis)。 |
| **Consistent Hashing** | - | **一致性哈希**。分布式缓存中用于数据分片和节点扩缩容的算法。 |