亿级流量下的短链系统的架构设计,看完不会你打我

前言

大家好,我是东东拿铁,95后奶爸程序员。短链系统相信大家都不陌生,业务逻辑也很简单,但从架构角度,许多点是需要我们可以深入了解的。在各类大厂的面试中,如何设计一个短链系统,也是设计题中的高频问题。

下面从系统架构设计的角度,为大家介绍下短链系统的设计与实现,本文会重点介绍几个个人认为比较关键的地方,让大家看完后,能够真正了解设计一个短链系统的方方面面。

需求分析

短 URL 生成器,也称作短链接生成器,就是将一个比较长的 URL 生成一个比较短的URL,当浏览器通过短 URL 生成器访问这个短 URL 的时候,重定向访问到原始的长 URL目标服务器。

性能指标预估

预计每月新生成短 URL 5 亿条,短 URL 有效期 2 年,那么总 URL 数量 120 亿。

5亿 × 12月 × 2年 = 120亿

存储空间

每条短URL数据库记录大约1KB,总数据量约12TB(只算主库容量)

并发量

由于我们是短链系统,平均访问吞吐量我们预估大一些,预估100w吧,拍一个

项目难点

  • 数据量大,百亿级别短链信息

  • 高并发,支持100w qps

  • 高性能,接口响应速度10ms以内

系统设计

原始URL生成

我们采用预生成URL的形式,也就是说上线前把URL完成生成,有以下几个优势

  1. 前置生成,用户请求时没有复杂逻辑,只需要读取即可

  2. 减少了前置的URL生成时是否重复判断,因为数据量比较大,如果在用户请求时实时生成,则需要去判断是否有重复。

采用随机数来实现,6个字符,每个字符都用随机数产生(用0~63的随机数产生一个Base64编码字符)。为了避免随机数产生的短 URL 冲突,我们在预生成的时候检查该 URL 是否已经存在(用布隆过滤器检查)。因为预生成短URL是离线的,所以这时不会有性能方面的问题。

预生成

预生成URL我们使用HDFS服务器,预计使用大小120亿*6B = 67GB

我们将生成的URL无分割存储在文件中,示例如下

go 复制代码
`Wdj4FbOac5CHtvPD`

预生成时,我们读取文件6000K数据,也就是一次预加载100W个短链,并记载偏移量,方便下次读取。

读取后的数据我们放入redis队列中

redis 127.0.0.1:6379> LPUSH KEY_NAME VALUE1.. VALUEN

由于我们每次加载100W个短链,按照日均1600W的短链数据量预估,我们可以设置一个5分钟的定时任务,如果列表数量不足1w,就继续去HDFS中加载即可。

redis 127.0.0.1:6379> LLEN KEY_NAME

用户非自定义生成短链

先从队列中获取短链。

vbnet 复制代码
redis 127.0.0.1:6379> LPOP key

将短URL与长URL的映射关系存储在 HBase 数据库中。

用户自定义短URL

由于系统支持6位短链,为了防止与系统生成有重复的,我们要求用户最短使用7个字符作为短链网址。

URL Base64编码

编码是我们短链系统中大家需要特别关注的点。

标准 Base64 编码表如下。

其中"+"和"/"在 URL 中会被编码为"%2B"以及"%2F",而"%"在写入数据库的时候又和 SQL 编码规则冲突,需要进行再编码,因此直接使用标准 Base64 编码进行短URL 编码并不合适。URL 保留字符编码表如下。

所以我们在编码时,需要注意标准编码的+与/进行替换,如替换成-与=号。

也可以直接使用62位编码,一样可以规避问题

用户访问

对于用户通过客户端请求访问短 URL 的过程(即输入短 URL,请求返回长 URL),请求通过负载均衡服务器发送到短 URL 服务器集群,短 URL 服务器首先到缓存服务器中查找是否有该短 URL,如果有,立即返回对应的长URL短 URL 生成服务器构造重定向响应返回给客户端应用。

如果缓存没有用户请求访问的短 URL,短 URL 服务器将访问 HBase 短 URL 数据库服务器集群。如果数据库中存在该短 URL,短 URL 服务器会将该短 URL 写入缓存服务器集群,并构造重定向响应返回给客户端应用。如果 HBase 中没有该短 URL,短 URL 服务器将构造 404 响应返回给客户端应用。

重定向

301&302区别

满足短 URL 重定向要求的 HTTP 重定向响应码有 301 和 302 两种,其中 301 表示永久重定向,即浏览器一旦访问过该短 URL,就将重定向的原始长 URL 缓存在本地,此后不再请求短 URL 生成器,直接根据缓存在浏览器(HTTP 客户端)的长 URL 路径进行访问。

302 表示临时重定向,每次访问短 URL 都需要访问短 URL 生成器。

一般说来,使用 301 状态码可以降低服务器的负载压力,但无法统计短 URL 的使用情况,我们的架构设计完全可以承受这些负载压力,因此使用 302 状态码构造重定向响应。

说在最后

本文从系统架构设计的角度,简单分析了下短链系统的设计与实现,但中间也有一些细节没有介绍道

  1. 短链URL过期清理
  2. 同一个URL重复登记的情况下的资源浪费

新人码字,欢迎留下你的评论与我一同交流,提出宝贵的意见,我们一起共同进步~

相关推荐
2401_8543910811 分钟前
Spring Boot大学生就业招聘系统的开发与部署
java·spring boot·后端
虽千万人 吾往矣32 分钟前
golang gorm
开发语言·数据库·后端·tcp/ip·golang
这孩子叫逆1 小时前
Spring Boot项目的创建与使用
java·spring boot·后端
coderWangbuer2 小时前
基于springboot的高校招生系统(含源码+sql+视频导入教程+文档+PPT)
spring boot·后端·sql
攸攸太上2 小时前
JMeter学习
java·后端·学习·jmeter·微服务
Kenny.志2 小时前
2、Spring Boot 3.x 集成 Feign
java·spring boot·后端
sky丶Mamba3 小时前
Spring Boot中获取application.yml中属性的几种方式
java·spring boot·后端
feng_xiaoshi3 小时前
【云原生】云原生架构的反模式
云原生·架构
千里码aicood4 小时前
【2025】springboot教学评价管理系统(源码+文档+调试+答疑)
java·spring boot·后端·教学管理系统
程序员-珍4 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发