2. 缓存基础回顾:缓存的定义、缓存层级与常见策略

在深入 OpenAPI 场景的缓存一致性之前,有必要先厘清缓存的核心概念。缓存并非简单的“存一下数据”,而是一种通过空间换时间、减少昂贵 I/O 或计算开销的系统性手段。本节从定义出发,逐步拆解缓存层级与淘汰策略,为后续的穿透保护与一致性设计奠定基础。

2.1 缓存的定义与核心价值

缓存(Cache)是位于原始数据源与请求方之间的临时存储层,用于保存频繁访问的数据副本。当请求到达时,若缓存命中则直接返回,避免重复查询数据库、远程服务或执行复杂计算。

维度 说明
核心目标 降低访问延迟、减少后端负载、提升系统吞吐量
典型场景 热点数据查询、会话状态、API 响应缓存、配置信息
代价 引入数据不一致风险、增加内存/存储开销、需要失效策略
关键认知:缓存不是万能药。在 OpenAPI 网关或微服务架构中,缓存策略必须与业务一致性要求对齐。读多写少、容忍短暂不一致的场景最适合引入缓存。

2.2 缓存层级:本地缓存与分布式缓存

根据缓存数据的存储位置与共享范围,缓存可分为两大层级。理解二者的差异是设计分层缓存架构的前提。

2.2.1 本地缓存(Local Cache)

数据存储在应用进程内部的内存中,如 Java 的 Caffeine、Guava Cache,或 Go 的 freecache。访问速度极快(纳秒级),但无法跨进程共享,且受限于单机内存容量。

  • 优点:零网络开销、延迟最低、实现简单。
  • 缺点:数据孤立、重启丢失、各节点缓存不一致。
  • 适用:配置信息、静态元数据、单机限流计数。

2.2.2 分布式缓存(Distributed Cache)

数据存储在独立的缓存服务中,如 Redis、Memcached。所有应用实例共享同一缓存池,支持更大容量和跨节点一致性。

  • 优点:容量可扩展、数据共享、支持持久化与集群。
  • 缺点:网络延迟(毫秒级)、序列化开销、依赖中间件稳定性。
  • 适用:用户会话、全局热点数据、API 响应聚合。
架构建议:在 OpenAPI 网关层,通常采用“本地缓存 + 分布式缓存”两级架构。本地缓存过滤高频重复请求,分布式缓存作为共享后备,兼顾速度与一致性。
缓存层级架构:本地缓存与分布式缓存 缓存层级架构 客户端请求 本地缓存(Caffeine / Guava) 延迟:纳秒级 · 容量:单机内存 分布式缓存(Redis / Memcached) 延迟:毫秒级 · 容量:集群可扩展 后端数据源(DB / API) 两级缓存逐级回退 未命中时下沉到下一层

2.3 常见缓存策略

缓存策略决定了数据何时被写入、何时被淘汰。错误的策略会导致缓存击穿、内存溢出或数据长期不一致。以下是最核心的两种策略。

2.3.1 LRU(Least Recently Used)

LRU 基于“最近访问时间”淘汰数据:当缓存容量满时,移除最久未被访问的条目。实现上通常采用哈希表 + 双向链表,保证读写时间复杂度为 O(1)。

  • 适用场景:访问模式符合局部性原理,近期访问的数据未来更可能被再次访问。
  • 变体:LRU-K(记录最近 K 次访问)、Segmented LRU(分段 LRU,如 Caffeine 的 W-TinyLFU)。
  • 注意:全表扫描或突发批量请求可能污染缓存,导致热点数据被意外淘汰。

2.3.2 TTL(Time To Live)

TTL 为每个缓存条目设置一个过期时间,到期后自动失效。这是保证缓存与数据源最终一致性的最直接手段。

TTL 类型 说明 典型值
固定 TTL 所有条目使用相同的过期时长 60s、300s
随机 TTL 在基础 TTL 上增加随机偏移,防止缓存雪崩 60s ± 10s
动态 TTL 根据数据热度或业务窗口动态调整过期时间 热点数据 30s,冷数据 600s
常见陷阱:仅依赖 TTL 无法解决缓存与数据库的强一致性问题。在 TTL 窗口内,如果数据库已更新但缓存未失效,就会返回脏数据。对于写频繁的场景,需要配合主动失效或 CDC(Change Data Capture)机制。
LRU 与 TTL 策略对比 常见缓存策略对比:LRU vs TTL LRU 淘汰策略 A B C ← 淘汰 最新 ← 容量满时淘汰最久未访问的条目 访问 B 后,B 移动到链表尾部 时间复杂度 O(1) TTL 过期策略 写入 有效 即将过期 过期 每个条目独立计时 到期后自动失效或惰性删除 随机 TTL 可防止雪崩 实际生产环境通常组合使用 LRU + TTL

2.4 策略组合与选型建议

单一策略往往无法满足复杂场景。下表总结了常见组合方式及其适用场景。

组合方式 工作机制 推荐场景
LRU + 固定 TTL 容量淘汰 + 时间过期双重保障 通用热点缓存,如用户信息、商品详情
LRU + 随机 TTL 避免大量缓存同时过期导致雪崩 高并发读场景,如秒杀商品列表
仅 TTL(无容量限制) 只依赖时间过期,不淘汰 小规模配置数据、字典表
仅 LRU(无 TTL) 只依赖访问频率淘汰 计算密集型结果缓存,如编译缓存
实践要点:在 OpenAPI 网关中,建议对每个缓存条目同时设置 LRU 最大容量和 TTL。容量限制防止内存泄漏,TTL 保证数据最终一致性。对于极端热点数据,可考虑使用 Caffeine 的 expireAfterWrite + maximumSize 组合。