系统设计:设计URL短链接工具

系统设计:设计URL短链接工具1*xOHz3T_iSShM2rRIT2bljA.png 这是一个系统设计问题,要求从头开始设计一个类似于TinyURL或Bitly的URL短链接工具。我们将涵盖从设计需求、架构和组件设计到高性能

1*xOHz3T_iSShM2rRIT2bljA.png

这是一个系统设计问题,需要从头设计一个类似于TinyURL或Bitly的URL短链接工具。我们涵盖从设计要求、架构和组件设计到高性能扩展和安全最佳实践的所有内容。

定义范围:功能性和非功能性需求

首先,您需要定义系统的功能和非功能需求。

有两个功能要求。

1. 给定一个长URL,您需要创建一个短URL。 2. 给定一个短URL,您需要将用户重定向到一个长URL。

1*jAM1f_jvXWxmPVRjiweF0g.png

服务的非功能性需求优先考虑低延迟(快速响应)和高可用性(始终开启)。

1*jNP-rIMTYsFG6wq8Hu4cnA.png

明确业务问题

为了持续了解系统的规模,您可能需要提出以下问题:

• 使用情况:估计每秒需要创建的URL 数量(假设1000)。字符:可以使用数字、字母(字母数字字符)和其他符号吗? (假设字母数字字符)。 •唯一性:即使多个用户提交相同的长URL,每次生成的短URL是否唯一?(此设计假设唯一性。)

估算:数据计算

您需要使用此信息来计算缩短的URL 的长度。当然,您希望使其尽可能短,但您还需要考虑每年创建的URL 数量。

1*KSIMBkGNZ7RzwWQRZ22uNA.png

首先,估计随着时间的推移您将需要多少个唯一URL。一般方法是规划至少几年的运营。为了简化计算,我们假设10 年的数据。

1年的秒数:1分60秒1小时60分钟10年的URL总数:100031536万=3153.6亿个唯一URL

这意味着数据库每秒必须处理1000 次写入,每年产生1000606024365=315 亿个URL。假设读取次数通常是写入次数的10 倍,这意味着每秒读取次数超过10×1000=10000 次。

现在您需要计算出有多少字符可以为未来10 年的数量提供足够的独特缩短URL。考虑到字符集大小为62,URL标识符的长度可以计算如下:

• 621=62 个唯一URL(1 个字符) • 62=3844 个唯一URL(2 个字符) • …等等。

1*v92u6EyCjrSdC2G9dfdkzQ.png

继续计算,我们发现62(大约3.5 万亿)是第一个大于估计的3150 亿个所需URL 的值。

因此,缩短的URL 应至少为7 个字符,以支持未来10 年的预期增长。

高层次架构

我们的系统有以下主要组成部分:

用户:用户应该提交长URL以生成短URL,或者提交短URL并被重定向到长URL。

负载均衡器:所有这些请求都经过负载均衡器。负载均衡器在多个Web 服务器实例之间分配流量,以确保高可用性和负载均衡。

Web 服务器:这些服务器副本处理传入的HTTP 请求。

URL短链接服务:您还需要一个URL短链接服务,其中包括生成短URL、存储URL映射以及检索原始URL进行重定向的核心逻辑。

数据库:存储短URL和长URL之间的连接。在设计数据库之前,您应该考虑缩短的URL 的潜在存储要求。

每个URL 都包含一个唯一标识符(大约7 个字节)、一个长URL(最多100 个字节)和用户元数据(估计为500 个字节)。这意味着每个URL 最多需要1000 个字节。根据预期量,这相当于大约315 TB 的数据。

1*mMbzPSeZtYyVyjcmi2rqVw.png

在继续之前,让我们考虑一下单个Web 服务器的API 设计。

API设计

让我们为我们的服务定义基本的API 操作。根据您的功能要求,您将使用REST API 并需要两个端点。

1. 创建缩短的URL (POST**/urls**)

输入:带有长URL 的JSON 负载{\”longUrl\” : \”[https://example.com/very-long-url](https://example.com/very-long-url)\’}

输出:包含缩短的URL {\”shortUrl\” : \”[https://tiny.url/3ad32p9](https://tiny.url/3ad32p9)\’} 和201 Created 状态代码的JSON 负载。

如果请求无效或格式错误,则返回400 错误请求响应;如果系统上已存在请求的URL,则返回409 冲突。

2. 重定向到长URL (GET**/urls/{shortUrlId}**)。

输入:shortUrlId 路径参数

输出:响应301 永久移动。响应正文包含新创建的缩短URL,格式为JSON{ \’shortUrl\’: \’https://tiny.url/3ad32p9\’ }。

1*wNufw9wtsv-tV0G20eDuAA.png

301 状态代码表示您的浏览器正在缓存信息。这意味着下次用户输入短URL 时,浏览器将自动重定向到长URL,而无需再次联系服务器。

但是,如果您想跟踪每个请求的分析并确保它通过您的系统,则可以使用302 状态代码。

数据库:存储短URL

下一部分是数据库层。该层存储短URL 和长URL 之间的映射。必须针对快速读写操作进行优化。

模式可以很简单。对短URL ID 和长URL 使用主键,并可能创建元数据字段。

{

\’shortUrlId\’: \’3ad32p9\’,

\’longUrl\’: \’https://example.com/very-long-url\’,

\’创建日期\’: \’2024-03-08T12:00:00Z\’,

\’用户ID\’: \’用户123\’,

“点击”: 1023,

\’元数据\’: {

\’title\’: \’网页示例\’,

\’tag\’: [\’示例\’, \’网络\’, \’URL 缩短器\’],

\’到期日\’: \’2025-03-08T12:00:00Z\’

},

\’isActive\’: true

}

这里要考虑的主要问题是从数据库读取的次数。通常,如果每秒写入1000 次,则每秒至少可以读取10-100000 次。

在这种情况下,您应该使用支持快速读写的高性能数据库。这意味着您需要使用NoSQL 数据库(诸如MongoDB 之类的文档存储、诸如Cassandra 之类的宽列存储或诸如DynamoDB 之类的键/值存储)。这是因为NoSQL 数据库是专门为处理大规模扩展而设计的。

1*qDll9-tFr2I2OxhWO3wSHg.png

它不符合ACID,但我不关心这一点,因为我不做大量JOIN 或复杂查询,而且我不需要ACID 规则或原子事务。

URL短链接服务

系统的核心部分之一是URL短链接服务。即使不同的长URL 指向相同的短URL,此服务也会生成短URL,而不会引起冲突。

有多种方法可以实现此服务。这里是其中的一些:

•哈希:生成长URL 的哈希并使用其中的一部分作为标识符。但是,哈希可能会导致冲突。 • 自增ID:使用数据库的自增ID 并将其编码为短字符串。这确保了唯一性,但也可以预测。 • 自定义算法:设计自定义算法,将字符组合起来生成唯一的ID,以确保唯一性和不可预测性。

例如,可以生成一个非常简单的方法——来避免冲突。

将所有可能的7 字符密钥作为密钥存储在数据库中。键是生成的URL,值是布尔值。如果为true 则表示该URL 已在使用中,如果为false 则表示该URL 可用。映射。

因此,每当用户请求生成密钥时,您都可以在此数据库中找到当前未使用的URL,并将其映射到请求正文中的长URL。

在这种情况下,您愿意使用SQL 数据库还是NoSQL 数据库?让我们考虑一个场景。两个用户请求缩短一个长URL,并且两个用户都映射到该数据库中的相同键。

1*b0c8CnuESVxCE2-Ux7QPqA.png

在这种情况下,URL 将被映射到其中一个请求,而另一个请求将被破坏。所以我们使用具有ACID 属性的SQL。您可以在此处为每个会话创建一个事务以单独执行这些步骤。这样的话,就不会出现这个问题。

高可用性和低延迟

当前系统显然无法处理每秒1000 个URL 的流量。

1*eN5OY1eSi9SnGHqgVgF9bg.png

缓存

为了提高可扩展性,您首先需要一个缓存层(例如Redis)来缓存流行的URL,以便在内存中快速检索。

某些URL 的访问可能比其他URL 更频繁,因此您需要一个驱逐策略来优先考虑频繁访问的项目。适合该场景的两种缓存删除策略是:

•LRU 逐出策略:首先删除最近最少访问的项目。对于URL短链接服务来说,这种策略非常有效,因为它保证了最常访问的、最新的URL都保存在缓存中。这可以显着减少热门链接的访问时间。 • 或者,基于TTL 的逐出策略:为每个缓存条目分配固定的生存时间(TTL)。当条目的TTL 过期时,该条目将从缓存中删除。对于仅在短时间内流行的URL,TTL 策略对于URL 短链接服务很有用。

1*oDV7pndeZqmTmRrthz5a3Q.png

TTL还有助于自动更新缓存内容,并且可以与其他策略(例如LRU)结合使用,以更有效地管理缓存。

数据库扩展:结合复制和分片

为了确保您的数据库支持高可用性、容错性和可扩展性,您必须实施复制和分片策略。

考虑到7个字符集中有3.5T个唯一URL,我们可以使用基于键的分片将URL记录均匀分布在多个分片上。

假设分布在3 个分片上,每个分片存储大约1.16T 的URL。随着URL 数量的增加,这可以确保系统的可扩展性。

您还可以在每个分片内实现主/从复制,以确保高可用性和容错能力。此配置允许在节点发生故障时快速故障转移和恢复。

1*68H1bEHS3eYotv9dBy9hmg.png

此外,如果您的服务面向全球用户,您可以考虑地理分片和复制,以最大程度地减少延迟并改善不同区域的用户体验。

这种组合使该服务能够处理大量URL 缩短和重定向,几乎没有停机时间,并且响应时间更快。

1*XHmu-wQLQwyKAHztn3zIeA.png

安全考虑

我们服务的安全考虑因素包括:

•输入验证:用户提交的所有URL 都必须经过净化。您应该检查有效的协议(HTTP、HTTPS 等)并确保URL 的格式正确。这有助于防止注入攻击。 •速率限制:您可以通过限制来自单个源的请求数量来保护您的服务免受DDoS 攻击。考虑使用令牌桶算法。 •监控和日志记录:需要强大的日志系统(例如ELK堆栈)。这使您可以分析日志以查找瓶颈和可疑活动,以确保整体系统的健康状况。 • 混淆:您不希望短URL 被轻易预测。可以在生成算法中添加随机性,以防止攻击者猜测有效链接。 • 链接过期:您可以选择允许用户为缩短的URL 设置过期日期。这限制了潜在恶意链接的生命周期。

#以上关于系统设计:内容源网络涉及到URL短链接工具的设计,仅供参考。相关信息请参见官方公告。

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/92662.html

(0)
CSDN's avatarCSDN
上一篇 2024年6月28日 上午3:09
下一篇 2024年6月28日 上午5:34

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注