URL 缩短器系统设计:链接缩短器的幕后工作原理
"设计一个 URL 缩短器"是最受欢迎的系统设计面试问题之一——这是有充分理由的。它涉及哈希、数据库、缓存、负载均衡和分布式系统,都隐藏在一个看似简单的产品中。
在本指南中,我们将介绍 URL 缩短器的实际工作原理、关键设计决策以及大规模运营中的权衡。
基本流程
URL 缩短器做两件事:
- 1缩短: 获取一个长 URL 并生成短代码
- 2重定向: 当有人访问短 URL 时,将他们重定向到原始 URL
以下是高级流程:
用户创建短链接:
长 URL → 生成短代码 → 存储映射 → 返回短 URL
用户点击短链接:
短 URL → 查找代码 → 找到长 URL → 301 重定向
生成短代码
核心挑战是生成唯一且简短的代码。有几种方法:
方法 1:Base62 编码
使用字符 [a-zA-Z0-9] 将自增 ID 转换为 Base62 字符串:
- ID
1→1 - ID
62→10 - ID
238,328→ZZZ
7 字符的 Base62 代码支持 62^7 = 3.5 万亿个唯一 URL。
优点: 简单、长度可预测、无碰撞 缺点: 顺序 ID 容易预测(用户可以猜测其他短 URL)
方法 2:哈希
对长 URL 应用哈希函数(MD5、SHA-256)并取前 N 个字符:
SHA256("https://example.com/very/long/url") → "a3f2b8c1..." 短代码:"a3f2b8c"
优点: 相同输入始终产生相同输出(去重) 缺点: 哈希碰撞需要处理;固定哈希长度可能浪费空间
方法 3:随机生成
生成随机字母数字字符串并检查唯一性:
优点: 简单、不可预测 缺点: 每次创建时都需要碰撞检查;随着数据库填满速度会变慢
使用哪种方法?
大多数生产系统使用带有分布式 ID 生成器的 Base62 编码。它简单、无碰撞且高效。在 Linkly,我们使用类似的方法——您可以阅读更多关于 URL 缩短器如何工作 的内容以获得不太技术性的概述。
数据库设计
核心表很简单:
urls ├── id (主键,自增) ├── short_code (唯一索引) ├── long_url (目标地址) ├── created_at (时间戳) ├── user_id (创建者) └── click_count (反规范化计数器)
SQL 与 NoSQL
SQL(PostgreSQL、MySQL): ACID 合规性、强一致性、适合中等规模。大多数 URL 缩短器从这里开始。
NoSQL(DynamoDB、Cassandra): 更好的水平扩展能力,支持数十亿 URL。最终一致性对该用例来说是可接受的。
混合: SQL 用于 URL 映射(重定向需要强一致性),NoSQL 或时间序列数据库用于点击分析(高写入量,最终一致性就可以)。
处理重定向
当用户点击短链接时,系统必须:
- 1从 URL 解析短代码
- 2查找对应的长 URL
- 3返回 HTTP 重定向响应
301 与 302 重定向
- 301(永久): 浏览器缓存重定向。较少的服务器请求,但您无法看到重复点击。
- 302(临时): 浏览器每次都检查服务器。更多请求,但更好的点击跟踪。
大多数 URL 缩短器使用 302 重定向 以获得准确的点击跟踪,然后为 SEO 用例提供 301 作为选项。请参阅我们的 301 重定向 指南了解更多。
缓存
重定向需要快速进行——每毫秒的延迟都会影响用户体验。缓存至关重要:
内存中缓存(Redis/Memcached)
在内存中缓存映射 short_code → long_url:
GET /abc123 → 检查 Redis 中的"abc123" → 缓存命中?立即返回重定向 → 缓存未命中?查询数据库、缓存结果、返回重定向
一个小型 Redis 实例可以缓存数百万个 URL 映射。由于大多数流量来自相对较少的热门链接,缓存命中率超过 90% 很常见。
CDN 缓存
对于 301 重定向,CDN 边缘节点可以缓存重定向响应,从最靠近用户的位置提供,完全无需访问您的源服务器。
分析和点击跟踪
记录点击数据是一个写入密集型操作,不应该减慢重定向速度:
异步处理
- 1用户点击短链接
- 2系统立即返回重定向
- 3点击事件被推送到消息队列(Kafka、RabbitMQ、SQS)
- 4后台工作程序处理事件:解析用户代理、地理定位 IP、存储分析数据
这将快速重定向路径与较慢的分析管道解耦。
要捕获的数据
- 时间戳
- IP 地址(用于地理定位)
- 用户代理(用于设备/浏览器检测)
- Referrer 头
- 国家、城市(来自 IP 地理定位)
扩展考虑
读取密集型工作负载
URL 缩短器是极其读取密集型的。典型的比率可能是 100:1 读写比。这意味着:
- 优先优化重定向路径
- 积极使用缓存
- 为数据库添加读取副本
分布式 ID 生成
如果您跨多个服务器使用自增 ID,需要避免碰撞。选项:
- Snowflake IDs: Twitter 的方法——嵌入时间戳、机器 ID 和序列号
- UUID: 通用唯一但更长
- ID 范围: 为每个服务器分配一个 ID 范围进行分配
地理分布
在多个地区部署重定向服务器。东京的用户不应该需要往返到弗吉尼亚州的服务器进行重定向。
安全考虑
URL 缩短器可能被滥用于网络钓鱼和恶意软件分发。生产系统需要:
- URL 扫描 — 针对恶意软件和网络钓鱼数据库检查目标地址
- 速率限制 — 防止大规模创建恶意短链接
- 滥用报告 — 让用户报告可疑链接
- 预览页面 — 可选择在重定向前向用户显示链接指向的位置
附加功能
除了基本的缩短和重定向,生产 URL 缩短器还提供:
- 自定义域名 — 使用您自己的域名的 品牌短链接
- 自定义 slug — 选择您自己的短代码而不是随机字符
- 过期 — 在日期后停止工作的 有时间限制的链接
- 密码保护 — 需要密码才能访问目标地址
- A/B 测试 — 在多个目标之间轮换
- 地理定位 — 按国家/地区重定向
- 设备定位 — 移动设备与桌面设备 的不同目标地址
- 二维码 — 为任何短链接 生成可扫描代码
结论
URL 缩短器系统设计是一个很好的练习,因为它开始很简单,但揭示了复杂的层面:代码生成、数据库设计、缓存、分析管道和滥用防止。理解这些基础知识无论您是在为面试做准备还是构建自己的工具时都很有帮助。
想要使用生产 URL 缩短器而不构建自己的? 开始使用 Linkly — 所有上述架构,已准备好使用自定义域、分析和高级功能。
