系统设计实践(01) - 短链服务

系统设计实践篇的文章将会根据《系统设计面试的万金油》为前置模板,讲解数十个常见系统的设计思路。

设计目标

设计一个像TinyURL这样的URL缩短服务。该服务将提供一个较短的URL,重定向到原本长的URL。

系统设计实践(01) - 短链服务

一. 为什么我们需要URL短链

URL缩短用于为长URL创建更短的别名。我们称这些缩短的别名为短链接。当用户点击这些短链接时,它们会被重定向到原始URL。短链接在展示、打印、发送或发推时可以节省大量空间,而且便于用户手动输入。

例如,如果我们通过TinyURL缩短这个URL

https://www.educative.io/collection/page/5668639101419520/5649050225344512/5668600916475904/916475904

可以得到:

缩短后的网址几乎是实际网址的三分之一大小。

URL缩短用于优化跨设备的链接,跟踪单个链接以分析受众和活动表现,并隐藏关联的原始URL。

如果您以前没有使用过tinyurl.com,请尝试创建一个新的短网址,并花一些时间浏览他们提供的各种服务选项,对你理解有很大帮助。

二. 系统的需求与目标

你应该在面试一开始就明确要求。一定要问问题,找出面试官脑海中系统的确切范围。

我们的网址缩短系统应该满足以下要求:

功能性需求:

给定一个URL,我们的服务应该生成一个更短且唯一的别名。

当用户访问一个短链接时,我们的服务应该将他们重定向到原始链接。

用户应该能够选择一个自定义的短链接为他们的URL。

链接将在标准的默认时间间隔之后过期。用户应该能够指定过期时间。

非功能性需求:

系统应该是高度可用的。这是必需的,因为如果我们的服务停止,所有的URL重定向将开始失败。

URL重定向应该实时发生,延迟最小。

缩短的链接不应该是可猜测的(不可预测的)。

扩展性需求:

分析: 例如,发生了多少次重定向?

我们的服务也应该可以通过REST API被其他服务访问。

三. 容量估算与约束

短链系统从请求读写量上来说,属于是读取量很大的。与缩短一个URL相比,访问短链将会有大量的重定向请求。可以假设读和写的比率是100:1。

流量估算

假设我们每个月有 500M 的新 URL 缩短,读/写比为 100:1,我们可以预期在同一时期有 50B 的重定向。

100 * 500M => 50B

我们系统的每秒查询(QPS)是多少?

500 million / (30 days * 24 hours * 3600 seconds) = ~200 URLs/s

考虑到 100:1 的读/写比率,每秒 URL 重定向将是:

100 * 200 URLs/s = 20K/s

存储估计

假设我们将每个URL目标链接(以及相关的缩短链接)存储5年。因为我们预计每个月有5亿个新url,所以我们预计存储的对象总数将达到300亿个

500 million * 5 years * 12 months = 30 billion

让我们假设每个存储对象大约为500字节(这只是一个粗略的估计,我们稍后将深入研究),我们总共需要15TB的存储空间。

带宽估计

对于写请求,由于我们预计每秒有200个新url,所以我们服务的总传入数据将是每秒100KB

200 * 500 bytes = 100 KB/s

对于读请求,由于我们预计每秒钟有大约20K的url重定向,所以我们的服务的总输出数据将是每秒10MB

20K * 500 bytes = ~10 MB/s

内存估计

如果我们想缓存一些经常被访问的热点url,我们需要多少内存来存储它们?

如果我们遵循80-20原则,即20%的url产生80%的流量,我们希望缓存这些20%的热点url。

由于我们每秒有2万次请求,我们每天将会收到17亿次请求。

20K * 3600 seconds * 24 hours = ~1.7 billion

要缓存20%的请求,我们需要170GB内存。

0.2 * 1.7 billion * 500 bytes = ~170GB

这里需要注意的一点是,由于会有很多重复的请求(相同的URL),因此,我们的实际内存使用量将少于170GB。

估算概述

假设每个月有5亿个新url,读:写比率为100:1,下面是对我们服务容量估算的总结。

创建短链 200/s

短链重定向 20K/s

入口流量 100KB/s

出口流量 10MB/s

五年需要存储量 15TB

内存用量 170GB

四. 系统API设计

一旦我们确定了需求,定义系统API总是一个好主意。这时候应该明确说明系统期望做到什么。

我们可以使用SOAP或REST API来公开服务的功能。下面是用于创建和删除url的api的定义。

createURL(api_dev_key, original_url, custom_alias=None, user_name=None, expire_date=None)

参数

api_dev_key (string) : 注册帐号的api开发密钥。此外,这将用于根据用户分配的配额限制用户

original_url (string): 可选的短链地址

custom_alias (string) : URL 的可选自定义键

user_name (string) : 用于编码的可选用户名
*• expire_date (string) : 可选的过期时间

返回

成功将返回缩短的URL。否则,它将返回错误代码。

deleteURL(api_dev_key, url_key)

其中url键是一个字符串,表示要检索的缩短的url。成功的删除返回URL Removed。

我们如何发现和预防滥用?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzdgsf.html