• 该如何设计一个短链系统?
  • 发布于 2个月前
  • 113 热度
    0 评论
前言

短链系统相信大家都不陌生,业务逻辑也很简单,但从架构角度,许多点是需要我们可以深入了解的。在各类大厂的面试中,如何设计一个短链系统,也是设计题中的高频问题。下面从系统架构设计的角度,为大家介绍下短链系统的设计与实现,本文会重点介绍几个个人认为比较关键的地方,让大家看完后,能够真正了解设计一个短链系统的方方面面。


需求分析
短 URL 生成器,也称作短链接生成器,就是将一个比较长的 URL 生成一个比较短的URL,当浏览器通过短 URL 生成器访问这个短 URL 的时候,重定向访问到原始的长 URL目标服务器。
性能指标预估
预计每月新生成短 URL 5 亿条,短 URL 有效期 2 年,那么总 URL 数量 120 亿。
5亿 × 12月 × 2年 = 120亿
存储空间
每条短URL数据库记录大约1KB,总数据量约12TB(只算主库容量)
并发量
由于我们是短链系统,平均访问吞吐量我们预估大一些,预估100w吧,拍一个
项目难点
1.数据量大,百亿级别短链信息
2.高并发,支持100w qps
3.高性能,接口响应速度10ms以内

系统设计
原始URL生成
我们采用预生成URL的形式,也就是说上线前把URL完成生成,有以下几个优势:
1.前置生成,用户请求时没有复杂逻辑,只需要读取即可
2.减少了前置的URL生成时是否重复判断,因为数据量比较大,如果在用户请求时实时生成,则需要去判断是否有重复。

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


预生成
预生成URL我们使用HDFS服务器,预计使用大小120亿*6B = 67GB
我们将生成的URL无分割存储在文件中,示例如下
`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
用户非自定义生成短链
先从队列中获取短链。
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重复登记的情况下的资源浪费
新人码字,欢迎留下你的评论与我一同交流,提出宝贵的意见,我们一起共同进步~
用户评论