TL;DR
- 场景: 高并发读多写少业务,数据库顶不住,需要提升吞吐与稳定性
- 结论: 本地缓存做极致读性能,分布式缓存做共享与扩展,多级缓存兼顾一致性与成本
- 产出: 可对照的版本矩阵与错误速查卡
版本矩阵
| 组件/能力 | 版本/年份 | 已验证 | 说明 |
|---|---|---|---|
| 本地缓存:Guava Cache | 32.x(2025) | 是 | 适合高频读、低变化数据 |
| 本地缓存:Ehcache | 3.x(2025) | 否 | 仅概述特性 |
| 分布式缓存:Redis | 7.2(2024–2025) | 是 | 覆盖旁路/穿透/写回与分布式锁 |
| 会话:Spring Session + Redis | 3.x(2025) | 部分 | 方案被提及 |
| 分布式锁实现 | SETNX + 过期 | 是 | 若需更稳妥可评估 Redisson |
缓存使用场景
使用场景
-
数据库存储优化方案
- 分库分表: 当单表数据量超过500万条时,查询性能显著下降
- 读写分离: 主库负责写操作,多个从库分担读请求
-
缓存系统的关键作用
- 减轻数据库压力:热点数据存储在Redis等内存数据库中,TPS可从2000提升至50000+
- 典型缓存策略:旁路缓存模式(Cache Aside)、读写穿透模式(Read/Write Through)、写回模式(Write Behind)
-
性能对比数据
- MySQL单机QPS:约2000-4000
- Redis单机QPS:约10万
- 缓存命中率建议维持在80%-95%之间
本地缓存(Local Cache)
概念与定义
本地缓存是指将数据存储在应用程序所在服务器的内存中,通过内存直接访问数据的缓存机制。
常见实现方式
-
基础实现:
ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>(); cache.put("key", "value"); -
专业缓存框架:
- Guava Cache: Google提供的轻量级缓存工具,自动加载、过期策略、缓存回收监听
性能优势
- 访问速度快: 内存级访问速度(纳秒级),无网络I/O开销
- 降低外部依赖: 减少对远程缓存服务的调用
局限性
- 容量限制: 受JVM堆内存大小制约
- 一致性问题: 集群环境下数据同步困难
- 功能局限: 缺乏专业的持久化机制
分布式缓存
主流分布式缓存系统
- Redis: 支持多种数据结构,提供持久化功能
- Memcached: 简单高效的键值存储
- Tair: 阿里和美团开发的分布式KV存储系统
Guava Cache
核心特性
- 自动加载机制: 支持在缓存未命中时自动从数据源加载值
- 多种缓存回收策略:
- 基于容量: 当缓存项数量超过指定值时回收
- 基于时间: 访问过期(expireAfterAccess)/写入过期(expireAfterWrite)
- 基于引用: 使用弱引用或软引用存储键或值
- 高性能并发支持: 采用类似ConcurrentHashMap的并发设计
基础用法示例
LoadingCache<Key, Value> cache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.recordStats()
.build(new CacheLoader<Key, Value>() {
public Value load(Key key) throws Exception {
return createExpensiveValue(key);
}
});
错误速查
| 症状 | 根因定位 | 修复方案 |
|---|---|---|
| 请求突增后 DB/Redis 抖动、RT 飙升 | 缓存击穿 | 热点 Key 逻辑过期 + 互斥重建 + 预热 |
| 命中率低、后端被打穿 | 缓存穿透 | 布隆过滤器/负缓存、参数校验、限流 |
| 大面积超时并发报错 | 缓存雪崩 | TTL 加随机抖动、分批失效、热点永不过期 |
| 某些节点数据不一致 | 本地缓存与分布式缓存失效不同步 | 失效广播、版本戳、缩短 TTL |
| 频繁 Full GC、应用卡顿 | 本地缓存容量过大 | 限制 maximumSize/weight |