这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
本地缓存
性能瓶颈的再思考
分片计数方案上线后,系统性能提升了很多。
但我发现了一个有趣的现象:
监控数据:
热门文章(前 100 篇):
- 访问量:占总访问的 80%
- Redis QPS:约 5000
- 响应时间:平均 5ms
普通文章:
- 访问量:占总访问的 20%
- Redis QPS:约 1000
- 响应时间:平均 8ms
热门文章的访问太频繁了!
虽然 Redis 很快,但:
- 每次请求都要网络往返
- 网络延迟至少 1-2ms
- 高峰期网络可能拥堵
能否再优化?
我想到了本地缓存。
本地缓存原理
传统方案:
用户请求 → 应用服务器 → Redis(网络往返)
本地缓存方案:
用户请求 → 应用服务器(本地内存)→ 命中则返回
↓
未命中 → Redis(网络往返)
优势:
- 本地读取速度极快(纳秒级)
- 减少 Redis 压力
- 降低网络延迟
劣势:
- 数据可能不一致
- 占用应用服务器内存
- 需要处理缓存失效
实现方案
方案 1:简单内存缓存
点赞计数本地缓存
方案 2:LRU 缓存
方案 3:多级缓存
缓存一致性
问题:多实例缓存不一致
场景:多个应用服务器
服务器 A:
- 本地缓存:article:123:like_count = 100
服务器 B:
- 本地缓存:article:123:like_count = 100
用户点赞(请求到达服务器 A):
- 服务器 A:更新 Redis → 101
- 服务器 A:更新本地缓存 → 101
- 服务器 B:本地缓存仍是 100(旧数据)
结果:不同服务器返回不同的值
解决方案 1:短 TTL
解决方案 2:主动失效
解决方案 3:版本号
性能对比
测试代码
实际效果
监控数据
本地缓存上线后:
热门文章访问:
- 本地缓存命中率:95%
- Redis QPS:从 5000 降到 250
- 响应时间:从 5ms 降到 0.1ms
应用服务器:
- CPU:从 45% 降到 20%
- 内存:增加约 100MB(可接受)
用户体验:
- 页面加载更快
- 点赞响应更流畅
适用场景
适合使用本地缓存的场景:
1. 热点数据(访问频繁)
2. 可容忍短暂不一致
3. 读多写少
4. 数据量不大
不适合使用本地缓存的场景:
1. 数据实时性要求高
2. 数据量大(内存有限)
3. 频繁更新
4. 需要强一致性
课后练习
练习 1
本地缓存和 Redis 缓存有什么区别?如何选择?
参考答案(3 个标签)
缓存架构设计性能
对比:
| 特性 | 本地缓存 | Redis 缓存 |
|---|---|---|
| 读取速度 | 极快(纳秒级) | 快(微秒级) |
| 容量 | 受应用服务器内存限制 | 可扩展(集群) |
| 一致性 | 多实例不一致 | 全局一致 |
| 网络开销 | 无 | 有 |
| 适用数据 | 热点数据 | 通用数据 |
选择建议:
使用本地缓存:
- 热点数据(如热门文章)
- 配置数据
- 不变数据
- 读多写少
使用 Redis 缓存:
- 通用数据
- 需要全局一致
- 数据量大
- 频繁更新练习 2
如何实现本地缓存的”预热”?
参考答案(3 个标签)
缓存预热性能优化
预热方案:
练习 3
本地缓存如何实现”防雪崩”?
参考答案(3 个标签)
缓存雪崩高可用
防雪崩方案:
练习 4
如何监控本地缓存的命中率?
参考答案(3 个标签)
监控缓存性能指标
监控方案:
练习 5
多实例环境下,如何保证本地缓存的一致性?
参考答案(3 个标签)
分布式缓存一致性架构
方案对比:
| 方案 | 实现复杂度 | 一致性 | 性能 |
|---|---|---|---|
| 短 TTL | 低 | 最终一致 | 中 |
| Pub/Sub | 中 | 最终一致 | 高 |
| 版本号 | 中 | 最终一致 | 高 |
| 定期刷新 | 低 | 最终一致 | 低 |
推荐:短 TTL + Pub/Sub
思考题
-
本地缓存会占用应用服务器内存,如何控制内存使用?
-
如果本地缓存和 Redis 数据不一致,如何处理?
-
如何实现本地缓存的”按需加载”?
💡 提示:这些问题没有标准答案,建议结合实际情况深入思考。
