Lesson 0008 · 系统设计 · Phase 2 数据层 · 综合案例
大案例 I:短链服务完整版
与你的 Mission 的关系
Lesson 0001 拆过短链的骨架,这次是血肉版——每个深挖点都标了它来自哪一课。这个「先骨架、后血肉、零件各归其位」的过程,就是你自己上考场时的思维过程模板。
§1 · Step 1澄清需求(5–8 分钟)
| 类别 | 内容 |
|---|---|
| 功能(MVP) | ① 长链 → 短码;② 短码 → 302 跳转。明确不做:自定义短码(可作扩展提一句)、访问报表、账号体系 |
| 非功能 | 读远多于写,读写比 100:1;跳转延迟 <100ms(用户体感);可用性三个 9 起步(短链挂了,挂的是别人的分享链接);短码永久有效 → 数据只增不减 |
| 规模假设 | 每月新增 1 亿条(先确认这个数字再往下算!) |
§2 · Step 2容量估算(5 分钟)
| 指标 | 计算 | 架构暗示 |
|---|---|---|
| 写 QPS | 10⁸ ÷ (30×86400) ≈ 40/s,峰值 ×3 ≈ 120/s | 写入压力很小——写路径不需要花哨优化 |
| 读 QPS | 40 × 100 = 4,000/s,峰值 ~12,000/s | 读是主战场 → 缓存是第一杠杆(L5) |
| 存储 | 1 亿/月 × 5 年 = 60 亿条 × 500B ≈ 3 TB(×2 副本 = 6 TB) | 单机盘放得下但增长无界 + 读 QPS 高 → 按分布式 KV 设计(L6) |
| 短码长度 | base62 的 7 位:62⁷ ≈ 3.5 万亿,覆盖 60 亿绰绰有余 | 7 位定死,不用纠结 |
估算的「决策回指」
注意每个数字后面那列——数字不落地到决策就是表演(Lesson 0002 的要求)。40 写/120 读这个对比直接决定了后文的架构重心。
§3 · Step 3高层设计(12–15 分钟)
┌──────────────┐
写 POST /shorten ─▶│ LB(L7) │◀── 读 GET /:code
└──────┬───────┘
▼
┌─────────────────────────┐
│ 无状态 API 集群(L3) │
└───┬───────────────┬─────┘
▼ ▼
[ID 生成服务] [Redis 缓存]◀─── 热点读全在这挡住
│ ▲ miss
▼ │
[分布式 KV 存储] ───────┘
(一致性哈希分片,L6)
两个关键设计点:
① 短码怎么生成?(深挖热点)
| 方案 | 机制 | 代价 |
|---|---|---|
| 哈希后截取 | md5(long_url) 取前 7 位 | 碰撞:要再查再试,并发下麻烦 |
| 自增 ID + base62 ✅ | 全局发号器发 ID,转 62 进制 | 发号器是单点 → 用号段模式:每台应用服务器一次领 1 万个号段,用完再领 |
| 预生成随机码池 | 提前生成随机码入队,用时取 | 要维护池子水位,复杂度高 |
② 数据模型
KV 一张表足矣:short_code → {long_url, created_at, owner}。按 hash(short_code) 分片——短码本身高基数、查询必带它,天然满足分片键三标准(L6)。没有跨表事务需求,NoSQL KV 是合理选择(L4 五问法验证)。
§4 · Step 4深入与权衡(15 分钟)
| 深挖点 | 讨论与权衡 |
|---|---|
| 301 vs 302 | 301 永久重定向:浏览器缓存后不再回源——省流量,但永远失去点击统计。302 每次回源:多一跳,但保留统计与改址能力。本产品若统计是付费点 → 302。说出代价再选(L1 第 4 步精神) |
| 缓存策略 | 读 4000 QPS 集中在热门短码(80/20)→ Redis + LRU 足够。恶意扫不存在的码?穿透防护:空值缓存 + 布隆过滤器(L5)。TTL 加抖动防雪崩 |
| 统计链路 | 点击计数异步化:跳转时发事件进 MQ(L7),消费者聚合后写报表库。同步计数会在热链上打爆 DB——这也是选 302 的连带理由 |
| 防滥用 | 开放写接口 = 被刷 + 被拿去做钓鱼跳板 → 写路径限流(L10)+ URL 黑名单审查(可异步,审核不过则禁用) |
| 多地域 | 读分散全球 → KV 存储跨区复制 + DNS 就近调度。跨区一致性要求低(短码写后不变),最终一致完全够用(L9) |
§5 · 随堂检测
§6 · 检索练习(本课最重要 25 分钟)
盖住上面的全部内容。拿一张纸或打开白板工具,从零开始用四步框架把短链服务完整推一遍——就像考场上一样。写完再回来对照,重点核对:每个数字有没有指回决策?每个组件选择有没有说出代价?
对照清单(自查 8 项)
① 澄清了「明确不做什么」② 读写比说出口了 ③ 每个估算数字后面跟着架构暗示 ④ 短码生成选了方案并说了代价 ⑤ 分片键选择给了理由 ⑥ 缓存三大问题至少提了穿透 ⑦ 301/302 讲成了权衡而非事实 ⑧ 限流/防滥用主动提了。
漏了哪条,就回哪课补:②③→L2、④⑤→L6、⑥→L5、⑦→L1、⑧→L10。
📌 把你的推演贴给老师,我按面试官标准给逐项点评。
§7 · 本周行动
行动任务(约 1 小时)
把 §6 的 25 分钟白板推演落成一份一页纸设计文档(约束 → 数字 → 架构图 → 权衡表)。这份文档是你 Lesson 0015「工作迁移」的练习品雏形——写文档的能力比白板能力更值钱。
§8 · 延伸资源
- 首选精读:Alex Xu《System Design Interview Vol.1》「Design a URL Shortener」章——对照它和你 §6 的推演,找差距[1]
- Snowflake ID:另一种全局发号思路(时间戳+机器ID), Twitter 为此发明[2]
- 四步框架速查表(推演时放在手边)
- 下一课 → Lesson 0009 CAP、PACELC 与一致性模型
💬 强烈建议:把 §6 的白板推演(哪怕是照片)发给我,我逐项按面试官评分标准反馈——这是本课程第一个「模拟面试」时刻。