2、缓存中间件基础

2.1 缓存的核心概念

缓存(Cache)是位于数据请求路径上的临时存储层,用于保存频繁访问的数据副本。当请求到达时,系统优先从缓存中读取数据,若命中则直接返回,避免每次请求都穿透到后端数据库或上游服务,从而显著降低响应延迟和系统负载。

缓存的核心价值: 将热数据存储在高速介质中,以空间换时间,实现毫秒级甚至微秒级的数据访问。

2.2 缓存命中率

缓存命中率是衡量缓存效率最关键的指标,计算公式如下:

缓存命中率 = 缓存命中次数 / (缓存命中次数 + 缓存未命中次数) × 100%

业界经验参考值:

命中率范围 健康度评估 常见原因
≥ 95% 优秀 缓存策略合理,数据访问局部性强
80% ~ 95% 良好 大部分热数据被缓存,仍有优化空间
60% ~ 80% 一般 缓存容量不足或过期策略过于激进
< 60% 较差 缓存设计存在严重问题,需重新评估
优化建议: 在 API Gateway 中,应针对不同路由设置独立的缓存 TTL(Time To Live),并监控每个缓存键的命中率,及时调整缓存策略。

2.3 缓存三大经典问题

在缓存使用过程中,必须警惕以下三种异常场景,它们会直接导致后端系统压力骤增甚至崩溃。

2.3.1 缓存穿透

定义: 请求查询一个缓存和数据库中都不存在的数据(如查询一个不存在的用户ID),导致每次请求都直接打到数据库。

解决方案:

  • 缓存空值: 将查询结果为 null 的 key 也缓存起来,设置较短的 TTL(如 30~60 秒)。
  • 布隆过滤器: 在缓存层之前加一层布隆过滤器,快速判断 key 是否可能存在。

2.3.2 缓存击穿

定义: 某个热点 key 在缓存过期的瞬间,大量并发请求同时访问该 key,导致所有请求都穿透到数据库。

解决方案:

  • 互斥锁: 只允许一个线程去数据库加载数据,其他线程等待。
  • 逻辑过期: 在 value 中存储过期时间,异步刷新缓存。

2.3.3 缓存雪崩

定义: 大量缓存 key 在同一时间过期失效,或缓存节点宕机,导致海量请求直接涌入数据库。

解决方案:

  • 过期时间随机化: 在基础 TTL 上增加随机偏移量(如 ±10%)。
  • 缓存高可用: 采用 Redis 哨兵或集群模式,避免单点故障。
  • 限流降级: 在 API Gateway 层对数据库请求进行限流保护。
缓存三大经典问题示意图 缓存穿透 查询不存在的数据 绕过缓存直达数据库 缓存击穿 热点 key 过期瞬间 高并发穿透 缓存雪崩 大量 key 同时过期 或节点宕机 后端数据库 / 上游服务 解决方案 • 缓存空值 • 布隆过滤器 • 参数校验 解决方案 • 互斥锁 • 逻辑过期 • 热点 key 永不过期 解决方案 • TTL 随机化 • 缓存高可用 • 限流降级

2.4 常见缓存中间件对比

在 API Gateway 场景中,最常用的缓存中间件包括 Redis、Memcached 以及本地缓存(如 Guava Cache、Caffeine)。以下是核心对比:

对比维度 Redis Memcached 本地缓存
数据结构 丰富(String、Hash、List、Set、Sorted Set、Bitmap、HyperLogLog 等) 仅支持 String(键值对) 通常为键值对,支持对象缓存
持久化 支持 RDB 和 AOF 持久化 不支持持久化 无持久化,随进程销毁
高可用 主从、哨兵、集群模式 客户端分片,无原生高可用 单机,无高可用
性能(读/写) 单机 10万+ QPS 单机 10万+ QPS 纳秒级,远高于网络缓存
分布式能力 原生集群,自动分片 客户端一致性哈希 不支持分布式
内存管理 可配置淘汰策略(LRU、LFU、TTL 等) LRU 淘汰,内存池管理 依赖 JVM 堆内存,需手动控制
典型应用场景 API 响应缓存、Session 共享、分布式锁、排行榜、计数器 简单键值缓存、Session 存储 热点数据本地缓存、配置缓存、元数据缓存
架构选型建议: 在 API Gateway 中,推荐采用 本地缓存 + Redis 分布式缓存 的两级缓存架构。本地缓存用于存储最热门的元数据(如路由规则、限流配置),Redis 用于存储用户维度的业务缓存数据,兼顾性能与一致性。

2.5 两级缓存架构示意

下图展示了 API Gateway 中常见的两级缓存部署模式:

API Gateway 两级缓存架构 客户端请求 API Gateway 处理层 本地缓存 (L1) Guava / Caffeine Redis 缓存 (L2) 分布式缓存 后端服务 / 数据库 查询流程:L1 本地缓存 → L2 Redis → 后端服务 逐级回源,每级未命中则向下查询并回填缓存
实践要点: 在 API Gateway 中,本地缓存建议存储路由规则、限流配额、API 元数据等变化频率极低的数据;Redis 缓存存储用户会话、接口响应快照、计数器等需要跨节点共享的数据。两级缓存之间需通过消息总线或 Redis Pub/Sub 实现失效通知,保证数据最终一致性。