现在的各种App如脉脉、微博基本不会让你发太长的网址,会给你转成短链。在面试的时候也经常会被问到如何实现一个支持高并发的短链接系统。
1 Scenario 场景
根据一个 long url 生成一个short url。
如 http://www.javadaily.cn => http://bit.ly/1ULoQB6
根据 short url 还原 long url,并跳转:
需和面试官确认的问题:
long url和short url必须一一对应吗?
Short url长时间没人用,需要释放吗?
1.1 QPS 分析
-
问日活,如微博100M
-
推算产生一条 tiny url 的 qps
-
假设每个用户平均每天 0.1(发10 条,有一条有链接) 条带 URL 的微博
-
平均写 QPS = 100M * 0.1 / 86400 = 100
-
峰值写 qps = 100 * 2 = 200
-
-
推算点击一条tiny url的 qps
-
假设每个用户平均点 1 个tiny url
-
平均写 QPS = 100M * 1 / 86400 = 1k
-
峰值读 qps = 1k * 2 = 2k
-
-
deduce 每天产生的新 URL 所占存储
-
100M * 0.1 = 10M 条
-
每条 URL 长度平均按 100 算,共 1G
-
1T 硬盘能用 3 年
-
由2、3 分析可知,并不需要分布式或者 sharding,支持 2k QPS,一台 SSD MySQL 即可。
2 Service 服务 - 逻辑块聚类与接口设计
该系统其实很简单,只需要有一个 service即可:URL Service。由于 tiny url只有一个 UrlService:
-
本身其实就是个小的独立应用
-
也无需关心其他任何业务功能
方法设计:
UrlService.encode(long_url):编码方法
UrlService.decode(long_url):解码方法
访问端口设计,当前有如下两种常用主流风格:
-
GET /<short_url> REST 风格
Return a http redirect resonse
-
POST /data/shorten(不太推荐,不符合 REST 设计风格,但也有人在用)
Return a short url
那么,你们公司的短链系统是选择哪种服务设计呢?
3 Storage 数据存取(最能体现实践经验)
-
select 选存储结构
-
scheme 细化数据表
3.1 SQL V.S NoSQL
需要事务吗?No,nosql+1
需要丰富的 sql query 吗?no,nosql+1
想偷懒吗?tiny url需要写的代码不复杂,nosql+1
qps高吗?2k,不高。sql+1
scalability 要求多高?存储和 qps 都不高,单机都能搞定。sql+1
- sql 需要自己写代码来 scale
- nosql,这些都帮你做了
是否需要 sequential ID?取决于你的算法
-
sql 提供 auto_increment 的 sequencetial ID,即 1,2,3
-
nosql 的 ID 不是 sequential
3.2 算法
long ur 转成一个 6 位的 short url。给出一个长网址,返回一个短网址。
实现两个方法:
-
longToShort(url)
把一个长网址转换成一个以http://tiny.url/
开头的短网址 -
shortToLong(url)
把一个短网址转换成一个长网址