题目重点:设计 create/redirect/可选过期与统计,按 1M 创建和 1B 跳转每日量级规划缓存,并用队列与 worker 吸收创建尖峰。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版 create 返回短码及状态;短码全局唯一,创建请求有幂等键。
- redirect 可接受已确认创建后短暂传播延迟,若必须立即全球可读需更贵的一致性路径。
- 过期和 analytics 是可选功能;具体保留期、目标 p99 和误用防护未由题目给出。
- 1M/day 约 11.6/s 平均,和 300–500 QPS、1,000 QPS 峰值可同时成立,但容量须按峰值/峰持续时长设计。
解题路线
- 分离读写链路。create 前端校验 URL 和幂等键,在持久写入队列/日志后才告知‘已接收’,worker 分配短码并写映射表;若 API 必须同步返回有效短码,则前端需预分配 ID 或等待 worker 完成,不能把仅入队当作已可跳转。
- 短码可用全局唯一 ID 的 base62 编码或租户/区域分段 ID;存储唯一约束防碰撞。映射表按 code 主键保存 target、创建/到期时间、状态、版本。
- redirect 按 code 先查就近缓存,miss 回源;每次校验 expiry/禁用状态,返回 301/302 需按产品缓存语义决定。1B/day 平均约 11.6k/s,热点比例决定缓存/分片,而非只按平均。
- 多 region 用 geo routing 到近端读副本/CDN,更新异步传播并监控复制滞后;跨 region 创建可通过 ID 空间分段避免冲突。
- 队列按峰值差额积压:若入站 1000 QPS、worker 稳态 500 QPS 持续 10 分钟,需承载至少 300k 待处理任务并留安全余量;重试要有幂等键、退避和 DLQ,不能无限循环。
- analytics 异步写事件流,别把每次跳转同步写热计数行;监控未完成创建、队列年龄、跳转 p99、过期误跳与地区滞后。
手动走一遍
用户 create 请求在尖峰时先以 requestId 持久入队。若 worker 处理完成前客户端重试,相同幂等键必须回到同一任务和最终短码;若入队成功但响应丢失,不能产生第二短码。短码可见后,近端 redirect cache miss 回源,缓存带剩余 TTL。
规模与取舍
创建写入规模按 1M/day 与 1000 QPS 峰值规划;短码索引存储 O(累计活跃链接),读缓存容量取决于热点集合。redirect 平均 1B/86400≈11.6k/s,峰均比需另估;队列积压量约 ∫max(0,入站率−处理率)dt,不能只给服务名不算容量。
易错点与追问
容易失分的边界
- 仅把请求放进内存队列就承诺不丢;队列必须持久化并处理重试/死信。
- 异步创建却同步返回‘已可跳转’,读副本还没映射。
- 用单一自增 ID 服务跨 region 创建,形成可用性和吞吐单点。
- 把 1M/day 平均约 12/s 误当峰值 1000 QPS 的矛盾。
- redirect 每次同步更新 analytics 热行,损害读路径。
继续深挖
- 自定义短码碰撞与恶意 URL 如何治理?
- 某短链突发全球热点如何处理 CDN 缓存和失效?
- 过期后是否可重用短码,旧 CDN 缓存怎么保证安全?
- 若要求 create 成功后全球立即可跳转,写一致性怎样变化?
