如何设计一个短链系统?


一、什么是短链系统?

短链指的是短的链接,对应的有长链。比如:

为什么要有短链呢?原因如下:

  • 短链更简洁,更方便传播
  • 方便统计该短链点击量等数据

二、如何设计一个短链系统?

1、短链的原理

短链其实就是通过请求短链服务拿到对应的长链,然后重定向(对应302状态码)到长链即可。

2、如何生成一个唯一短链?

如何选择生成唯一短链的算法?:说到唯一,那么我们最先想到的就是使用哈希算法通过长链去生成短链,而且一般会采用非加密型哈希算法(如MurmurHash),因为相比MD5SHA等加密性哈希算法来说,非加密型哈希算法的性能会更高(同时我们也不用保证这个场景的安全性)。

举个例子,我们使用Guava自带的MurmurHash算法来生成一个短链:

String url = "https://time.geekbang.org/column/intro/100020801";
// 转换出来的code是10进制的3394174629
long code = Hashing.murmur3_32().hashUnencodedChars(url).padToLong();

生成的10进制还是太长,能不能再短一点?:可以将10进制进一步转为62进制(因为在网址URL中,常用的合法字符只有09、az、A~Z这62个字符)

但是呢,虽然说哈希算法很小概率会出现哈希冲突,但也不是绝对的,所以我们要对哈希冲突做出一些解决方案:

  • 长链拼接字符串:对冲突的长链后面拼接一段字符串,如果还是冲突就再拼…然后通过短链拿到长链后,再把拼接的字符串去掉即可(但是MySQL要额外维护一个字段来存储拼接字符串)
  • 分布式ID生成短链:我们可以在生成的短链后面拼接一段分布式ID,因为分布式ID是全局唯一的,所以对应的短链也是全局唯一的(如果过长也可以转为对应的62进制)

3、短链如何存储?

我们一般采用关系型数据库来存储,如MySQL等,通过唯一索引来避免短链重复。

4、短链与长链转换过程

长链转换为短链的过程如下:

  1. 判断MySQL是否存在该长链,如果存在则直接返回对应的短链
  2. 通过哈希算法生成对应的短链,并存储到MySQL中
  3. 返回短链

短链转换为长链的过程如下:

  1. 判断MySQL是否存在该短链,如果存在则直接返回对应的长链,反之返回不存在

5、如何做性能优化?

短链系统如何请求量过大,可能会导致性能差的问题,所以我们可以做一下性能优化:

  • 数据库索引:在MySQL中对短链和长链字段添加索引,提高查询速度
  • 缓存:因为短链和长链的映射关系一般是固定不变的,所以我们可以通过添加缓存层来缓解我们的数据库压力,同时提高查询速度
  • 读写分离:短链服务肯定是读远大于写的,所以要做好读写分离
  • …(其他的就是针对高并发做性能优化的方案了)

三、Q&A

1、为什么短链重定向为长链不用301而用302?

因为301是永久重定向,服务器拿到长链后会对其缓存,这样我们后面的请求就不会再经过短链服务了(也就是不能统计数据),而302只是临时重定向,就不会出现这种问题。


文章作者: GaryLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GaryLee !
  目录