缓存概念与原理
缓存(Cache)是计算机系统中用于临时存储数据副本的高速存储层。在 API 系统中,缓存位于客户端与原始数据源之间,通过保存频繁访问的数据来减少对后端服务的请求压力,从而降低响应延迟、提升系统吞吐量。
核心思想:用空间换时间——用有限的存储空间换取更快的访问速度。
2.1 缓存的定义与工作原理
缓存本质上是一个键值存储系统。当请求到达时,系统首先检查缓存中是否存在所需数据;如果存在,则直接返回缓存数据(缓存命中);如果不存在,则从原始数据源获取数据,同时将数据副本写入缓存(缓存未命中)。
2.2 缓存命中与未命中
缓存系统的性能主要由两个指标衡量:命中率和未命中率。
| 术语 | 定义 | 影响 |
|---|---|---|
| 缓存命中 | 请求的数据在缓存中存在,直接返回 | 响应时间极短(微秒级),无后端压力 |
| 缓存未命中 | 请求的数据在缓存中不存在,需回源查询 | 响应时间增加(毫秒级),消耗后端资源 |
| 缓存穿透 | 请求的数据既不在缓存也不在数据源中 | 每次请求都穿透到后端,可能导致雪崩 |
| 缓存击穿 | 热点 key 在过期瞬间被大量并发请求 | 瞬间高并发冲击后端数据库 |
| 缓存雪崩 | 大量缓存同时过期,导致请求全部落到后端 | 后端负载骤增,可能引发系统崩溃 |
实践建议:API 缓存设计应追求 90% 以上的命中率。命中率低于 80% 时,需要检查缓存键设计、过期策略或数据访问模式是否合理。
2.3 缓存淘汰策略
缓存空间有限,当缓存写满时,必须按照特定规则移除旧数据,为新数据腾出空间。这些规则称为淘汰策略。以下是三种最常用的策略:
2.3.1 LRU(最近最少使用)
LRU 淘汰最长时间未被访问的数据。其核心假设是:如果数据最近被访问过,那么未来被访问的概率也更高。
- 实现方式:双向链表 + 哈希表
- 时间复杂度:O(1) 访问和淘汰
- 适用场景:大多数通用缓存场景,如浏览器缓存、API 响应缓存
- 缺点:偶发性的批量访问可能淘汰真正热点的数据
2.3.2 LFU(最不经常使用)
LFU 淘汰访问频率最低的数据。其核心假设是:访问频率低的数据未来被访问的概率也低。
- 实现方式:最小堆或多级链表(按频率分组)
- 时间复杂度:O(log n) 或 O(1)
- 适用场景:访问模式稳定的场景,如 CDN 缓存、热门内容缓存
- 缺点:新数据刚加入时频率低,容易被淘汰(冷启动问题)
2.3.3 FIFO(先进先出)
FIFO 淘汰最早进入缓存的数据。其核心假设是:先来的数据已经完成了它的使命。
- 实现方式:队列
- 时间复杂度:O(1)
- 适用场景:数据时效性强的场景,如会话缓存、日志缓存
- 缺点:不考虑访问频率和访问时间,可能淘汰热点数据
2.4 策略对比与选型
| 策略 | 淘汰依据 | 时间复杂度 | 内存开销 | 适用场景 |
|---|---|---|---|---|
| LRU | 最近访问时间 | O(1) | 中(链表 + 哈希表) | 通用 API 缓存、浏览器缓存 |
| LFU | 访问频率 | O(log n) ~ O(1) | 高(频率计数器) | CDN 缓存、热门数据缓存 |
| FIFO | 进入时间 | O(1) | 低(队列) | 会话缓存、临时数据缓存 |
选型注意:没有万能的淘汰策略。LRU 是大多数场景的默认选择;如果数据访问模式有明显的“热点”特征(如 20% 的数据占 80% 的访问),LFU 更优;如果数据有明确的过期时间或生命周期,FIFO 更简单高效。实际生产环境中,Redis 等缓存中间件通常支持多种策略配置,建议根据业务特征进行压测后确定。
2.5 缓存策略在 OpenAPI 中的体现
在 OpenAPI 规范中,缓存策略通过 Cache-Control 响应头字段与 API 契约结合。以下是一个典型的缓存配置示例:
paths:
/api/users:
get:
summary: 获取用户列表
responses:
'200':
description: 成功返回用户列表
headers:
Cache-Control:
schema:
type: string
example: "public, max-age=3600, s-maxage=7200"
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
上述配置中:
max-age=3600:客户端缓存 1 小时s-maxage=7200:共享缓存(如 CDN)缓存 2 小时public:允许任何中间缓存存储响应
课程关联:第 5 章将深入讲解如何在 OpenAPI 契约中精确描述缓存策略,包括 ETag、Last-Modified 和条件请求的契约定义。