缓存体系与数据层选型
0. 元信息
- 主题路径:
docs/topics/system-design/subtopics/caching-and-data-layer/README.md - 父主题:
system-design - 主分类:工程技术
- 辅助分类:计算机基础
- 适合对象:写过 SQL、用过 Redis、了解 CDN 基础的后端工程师
- 建议周期:1~2 周(每周 8~10 小时,重点是基准测试与失效演练)
- 前置知识:
capacity-and-architecture、db-and-sql;会用redis-cli与wrk - 最终目标:能为一个读写比 100:1 的业务选对缓存策略、解释 5 种写模式(Cache-Aside / Read-Through / Write-Behind / Write-Through / Bypass)、能解释雪崩/击穿/穿透的成因与防护,并能为新业务选对存储类型
1. 学习路线
缓存体系总览(CDN / 反向代理 / 进程内 / 分布式)
→ 缓存写策略五件套(Cache-Aside / Read-Through / Write-Behind / Write-Through / Bypass)
→ 缓存失效三件套(雪崩 / 击穿 / 穿透 / 热 key)
→ Redis 进阶(Lua / Stream / Cluster / Pub-Sub / Pipeline)
→ Memcached 与 Redis 的取舍
→ 关系数据库(MySQL / PostgreSQL / TiDB / CockroachDB / Aurora)
→ 文档数据库(MongoDB / FerretDB)
→ 列存与时序(ClickHouse / Cassandra / ScyllaDB / InfluxDB / TimescaleDB)
→ 向量数据库(Milvus / Weaviate / pgvector)
→ 对象存储与生命周期(S3 / OSS / MinIO + Glacier / 归档)
→ 冷热分层与归档
每一步都跑基准、写失效演练。
2. 阶段周数分配
精简子主题不固定周数。按 §3 顺序完成。
3. 九阶段表
| 阶段 | 核心知识 | 实践产出 | 学会标准 |
|---|---|---|---|
| 1 | 缓存体系总览 | 缓存分层图 | 能讲清 CDN / 反向代理 / 进程内 / 分布式 的边界 |
| 2 | 5 种写策略 | 5 个可运行示例 | 能为「读多写少」「写多读多」选对策略 |
| 3 | 缓存失效三件套 | 雪崩 / 击穿 / 穿透 演练 | 能复现 + 解释 + 防护 |
| 4 | Redis 进阶 | Lua 限流 + Stream 队列 | 理解 Lua 原子性、Stream 消息回溯 |
| 5 | Memcached vs Redis | 基准对比报告 | 知道什么时候用 Memcached |
| 6 | 关系数据库选型 | MySQL / TiDB 对比 | 知道何时分库分表 / 何时上分布式 |
| 7 | 文档 / 列存 / 时序 | Mongo / ClickHouse / InfluxDB | 能解释业务匹配 |
| 8 | 向量 / 对象存储 | Milvus + S3 | 能解释 RAG 与冷归档 |
| 9 | 冷热分层 | 自动迁移策略 | 写一份数据生命周期表 |
4. 第一周任务
精简版省略固定日程。先完成阶段 1~3:缓存体系总览 + 5 种写策略 + 失效演练。
5. 阶段通用验收
精简版省略;每个产出保留基准报告、命中/失效日志、版本。
6. 最终验收
精简版省略;以 §3 第 9 阶段和 §9.4 问题口述检查为准。
7. 综合项目
精简版省略;成果并入父主题百万 QPS 短链项目(5 种缓存模式 + 雪崩/击穿/穿透演练)。
本主题贡献
- 在父主题
system-design的综合项目「百万 QPS 短链」中,本主题(缓存体系与数据层选型)负责 5 种缓存写策略 + 失效三件套演练 + 存储选型:把 Cache-Aside / Read-Through / Write-Behind / Write-Through / Bypass 5 个模式用 Redis Lua + Memcached + 关系 / 列存 / 时序分别落地,复现雪崩 / 击穿 / 穿透 并给出防护代码。 - 工程动作:用
memtier_benchmark与redis-benchmark跑 Redis vs Memcached 基线;用 Redis Lua 写令牌桶 + singleflight 演示击穿防护;用 Bloom filter(redis-bloommodule 或BF.*)演示穿透;用 TTL 抖动(base + rand(0, jitter))演示雪崩防护;用 TiDB vs MySQL 跑读写 QPS 对比;用 ClickHouse 演示短链跳转 OLAP。 - 与 system-design 其它子主题对接:给 capacity-and-architecture 回填 Redis / Memcached QPS 与命中率(> 95%);给 consistency-and-messaging 写 Write-Behind 时的 Outbox 模板;给 reliability-and-observability 暴露
cache.hit_ratioSLI 与大 / 热 key 告警。
交付物清单:
cache/5_strategies.md:5 种写策略各 1 个端到端示例(短链 read / write),含伪代码 + 数据流图 + 失效路径;cache/failover/*.md:雪崩 / 击穿 / 穿透各 1 份演练报告,含复现脚本、QPS 跌停曲线、TTL 抖动 / singleflight / Bloom 的修复证据;bench/redis_vs_memcached.md:同 key size、同 QPS、同机器下两个工具的 P50 / P95 / P99 + 内存占用对照;bench/storage_matrix.md:MySQL / TiDB / ClickHouse / InfluxDB / Milvus 各跑 1 个查询特性(短链跳转 / 秒级跳转 OLAP / 分钟级 metrics / 100 维向量检索),附pgvector与Milvus的向量检索对照。
验收标准:
- 5 种写策略各跑通 ≥ 1 万次同 key 写,命中率 ≥ 95%;
- 雪崩演练:同一批次 1000 key 失效时 DB QPS 不超过阈值 1.5×;TTL 抖动修复后均匀打散;
- 击穿演练:单 hot key 0 命中下后端只产生 1 次回源请求(singleflight 验证);
- 穿透演练:Bloom filter 在
FPR ≤ 1%下拦截全部不存在 key;空值缓存 ≥ 5 分钟。
8. 推荐资料
精简版省略;使用 §9.3 和 §9.6 Source。
9. 学习资料汇聚(v0.3 自包含)
9.1 背景与动机
缓存几乎是性能优化的第一反应。1990 年代中期 Memcached 把内存 hash 表抽成网络服务;2009 年 Redis 用单线程 + 多数据结构 + Lua 改写了「分布式缓存」;2010 年代 CDN 把「地理缓存」变成互联网的基础设施。今天几乎所有大流量系统都至少 3 层缓存:CDN / 反向代理 / 进程内 / 分布式。学会选对缓存、写对失效,远比加机器重要。
数据层这边,2000 年代 MySQL 是默认答案;2010 年代 NoSQL 浪潮带来 MongoDB、Cassandra、HBase;2015 年后 NewSQL(TiDB / CockroachDB / Spanner)补齐「分布式 + SQL」;2018 年后时序与向量数据库独立成军。选型不是越新越好,是业务读写特征 + 一致性 + 成本的三元匹配。
9.2 概念地图
flowchart LR
Client[客户端] --> CDN[CDN 边缘缓存]
CDN --> Gateway[API 网关]
Gateway --> Local[进程内缓存 Caffeine/Map]
Local --> Distributed[分布式缓存 Redis/Memcached]
Distributed --> DB[数据层]
DB --> SQL[关系: MySQL/TiDB]
DB --> Doc[文档: MongoDB]
DB --> Column[列存: ClickHouse/Cassandra]
DB --> TS[时序: InfluxDB/TimescaleDB]
DB --> Vector[向量: Milvus/pgvector]
DB --> Object[对象: S3/OSS + 生命周期]
DB -.冷热分层.-> Archive[冷归档 Glacier/OSS 归档]
关系说明:每一层缓存解决「距离近 + 命中率高」;每一层存储解决「类型 + 一致性 + 成本」。缓存与存储共同回答「数据该存在哪里、用什么方式读」。
9.3 基础知识讲解
9.3.1 论文 / 规范
- Fitzpatrick, Distributed Caching with Memcached(2004,LiveJournal)。
- Sanfilippo, Redis Documentation(antirez.com)。
- DeCandia et al., Dynamo: Amazon’s Highly Available Key-value Store(2007,SOSP)。
- Corbett et al., Spanner: Google’s Globally-Distributed Database(OSDI 2012)。
- Corbett et al., Bigtable: A Distributed Storage System for Structured Data(OSDI 2006)。
- Chang et al., Bigtable(同上)。
- ONNX / Faiss / Milvus 论文:向量检索。
9.3.2 书
- Martin Kleppmann, Designing Data-Intensive Applications(2017)第 5~7 章。
- Salomon, Data Compression(Springer, 2007):压缩算法参考。
- Brad Fitzpatrick, Memcached 协议规范。
- Redis 7.x 官方文档。
- High Scalability 案例:Facebook Memcached 架构、Instagram Redis、Discord Cassandra。
9.3.3 博客 / 文档
- Redis 官方文档:Lua / Stream / Cluster。
- Memcached 官方 Wiki。
- Facebook Engineering: Memcache:大规模缓存实践。
- Instagram Engineering: Redis at Scale。
- Discord Engineering: Cassandra → ScyllaDB。
- ClickHouse 官方文档。
- Milvus 官方文档。
- AWS S3 生命周期与 Glacier。
9.3.4 人物
- Brad Fitzpatrick:Memcached 作者,LiveJournal。
- Salvatore Sanfilippo(antirez):Redis 作者。
- Jeff Dean:Google 大型系统性能。
- Martin Kleppmann:DDIA。
- Werner Vogels:Amazon Dynamo 思想。
- Murat Demirbas:CRDT / 分布式系统。
9.3.5 方法
- Cache-Aside 默认:读多写少时首选,应用层管缓存。
- Read-Through 把缓存当 DB 代理:业务不感知。
- Write-Behind 用队列异步回写:写多读多、容忍丢失。
- Bypass 直写:强一致、缓存只作临时。
- TTL 抖动:避免雪崩的关键。
- Mutex / singleflight:避免击穿。
- Bloom filter:避免穿透。
- 冷热分层:热数据走 Redis / SSD,温数据走列存,冷数据走对象存储 / 归档。
9.4 经典问题与经典案例
| 问题 | 为什么重要 | 最简答案 |
|---|---|---|
| Cache-Aside vs Read-Through | 业务是否感知缓存 | Cache-Aside 应用层管;Read-Through 缓存代理 |
| Write-Behind 怎么不丢消息 | 写异步回写有丢失风险 | Outbox + WAL + 异步重试 |
| 雪崩怎么防 | 大量 key 同时失效压垮 DB | TTL 抖动 + 后台刷新 + 多级缓存 |
| 击穿怎么防 | 热点 key 失效瞬间打 DB | singleflight / 互斥锁 / 永不失效 |
| 穿透怎么防 | 查询不存在的数据绕过缓存 | 布隆过滤器 / 空值缓存 / 接口校验 |
| 热 key 怎么发现 | 单 key 流量打满一个节点 | redis-cli --hotkeys / 客户端 hash 拆分 |
| Redis 与 Memcached 怎么选 | 内存数据库取舍 | 选 Memcached 当纯 KV;选 Redis 当需要 Lua / Stream / Pub-Sub |
| MySQL 与 TiDB 怎么选 | 单库与分布式 SQL 取舍 | 写 QPS < 5k 用 MySQL + 分库分表;写 QPS > 5k 或要 HTAP 选 TiDB |
| 列存 vs 时序 | ClickHouse vs InfluxDB | OLAP 选 ClickHouse;时序指标选 InfluxDB / TimescaleDB |
| 向量数据库选型 | RAG / 检索增强 | 量小用 pgvector;量大用 Milvus / Weaviate |
| 对象存储生命周期 | 成本控制 | 热 → 温 → 冷 → 归档 自动迁移 |
| CDN 命中率怎么提 | 决定源站压力 | 大文件分片 + 主动预热 + 边缘缓存 |
9.5 学习难点
- 概念难点:5 种写策略边界。卡点来自混用 Cache-Aside 与 Write-Behind;用写策略决策表对每个业务画「读路径 + 写路径 + 失效路径」。
- 思维难点:雪崩 vs 击穿 vs 穿透。卡点来自把三者当同一种问题;它们触发条件不同(批量失效 / 热点 key 失效 / 恶意查询不存在数据),防护手段也不同。
- 工程难点:Redis 大 key 与热 key。卡点来自发现与治理;用
redis-cli --bigkeys/--hotkeys+ 客户端 hash 拆分 + 多级缓存。
9.6 技术标准与接口
9.6.1 Entity
| 名称 | 版本 | 组织 | 状态 / 可访问性 |
|---|---|---|---|
| Redis | 7.x | Redis Labs | GA;BSD-3-Clause |
| Memcached | 1.6+ | Dormando | 维护;BSD-3-Clause |
| MySQL | 8.x | Oracle | GA;GPL-2.0 |
| TiDB | 7.x | PingCAP | GA;Apache-2.0 |
| ClickHouse | 23+ | ClickHouse Inc. | GA;Apache-2.0 |
| Cassandra | 5.x | Apache | GA;Apache-2.0 |
| ScyllaDB | 5.x | ScyllaDB | GA;AGPL-3.0(企业版另议) |
| MongoDB | 7.x | MongoDB Inc. | GA;SSPL |
| InfluxDB | 2.x | InfluxData | GA;MIT |
| TimescaleDB | 2.x | Timescale | GA;Apache-2.0 |
| Milvus | 2.x | LF AI | GA;Apache-2.0 |
| pgvector | 0.5+ | 社区 | 活跃;PostgreSQL 许可 |
| S3 / OSS / MinIO | 当前 | AWS / 阿里云 / 社区 | GA;各自许可 |
9.6.2 Scope
- 缓存解决「距离近 + 命中率高」;不替代存储。
- 关系数据库解决「强一致 + 事务」;列存解决「OLAP 聚合」;时序解决「指标写入」;向量解决「相似度检索」;对象存储解决「非结构化大文件」。
- 冷热分层解决「成本控制」。
9.6.3 Structure
- Cache-Aside:
read = cache.get(k) || db.get(k); cache.set(k)。 - Read-Through:缓存层负责从 DB 拉取。
- Write-Behind:写缓存后异步回写。
- Bypass:写直透。
- 雪崩防护:TTL = base + rand(0, jitter)。
- 击穿防护:singleflight / 互斥锁。
- 穿透防护:布隆过滤器。
- 生命周期:热 → 温 → 冷 → 归档。
9.6.4 Ecosystem
- 缓存客户端:Jedis / Lettuce / Redisson / go-redis / redis-py。
- 关系 DB 客户端:MySQL JDBC / pgx / GORM。
- 文档 / 列存 / 时序:各数据库官方驱动 + ORM。
- 对象存储:AWS SDK / 阿里云 OSS SDK / MinIO Client。
- 基准工具:
memtier_benchmark/redis-benchmark/wrk/tsbs。
9.6.5 Depth Tiers
| 层级 | 能力 | 缓存与数据层主题可观察标准 |
|---|---|---|
| L0 | 知道存在 | 知道 5 种写策略与多种数据库类型 |
| L1 | 看得懂示例 | 能读 Redis Lua / ShardingSphere 配置 |
| L2 | 能正确调用 | 能写 Cache-Aside + Lua 限流 + 多级缓存 |
| L3 | 能解释与排错 | 能复现雪崩 / 击穿 / 穿透并选对防护 |
| L4 | 能设计与扩展 | 能为新业务选型并设计冷热分层 |
本计划目标:L3。
9.6.6 Source
- Redis 官方文档 与 Memcached Wiki。
- TiDB 文档 与 ClickHouse 文档。
- Milvus 文档 与 pgvector。
- 引用快照:2026-07-30。
10. 常见误区
- 用”加缓存”代替「先想为什么慢」
- Cache-Aside 不处理并发写导致脏数据
- 雪崩只想到加机器,不知道 TTL 抖动
- 击穿用全局锁拖慢系统
- 穿透靠数据库兜底把 DB 打挂
- Redis 单 key 超过 1MB
- 把 Memcached 与 Redis 当成等价品
- 列存当主库用,写入慢
- 时序库当 OLAP 用,聚合慢
- 向量库滥用大模型生成 embedding
- 对象存储当文件系统用
- 冷数据不归档,白花钱。
11. 所有知识点分类(统一规则)
- 编程语言
- 数据结构与算法
- 计算机基础
- 工程技术
- Web 与后端
- 前端与客户端
- 数据与人工智能
- 项目与职业能力
- 安全与可靠性
本计划归属:工程技术 主 + 计算机基础 辅。