怎么样设计短链接系统?

短链接是什么?

短链接,顾名思义就是短的链接,能将很长的链接转化为短链接,并且能由短链接指向原来长链接所指向的地方。

为什么需要短链接?

  • 在很多地方,比如微博、推特限制了每一条博文内容长度,那么如果链接太长可能就无法发出去了。
  • 生成的二维码也更加容易识别些
  • 很多服务也是依靠长度计费的,少点链接的长度也能省下一些钱
  • 短链接也相当灵活。如果原来指向的地址发送改变,那么也容易指向新的地方

如何生成

Hash

最简单直接的方式其实是对长链接生成hash。然而这种方法却存在问题

  • 存在hash碰撞
  • 无法将短链接逆转为长链接

为了解决无法逆转的问题可以通过储存对应hash与链接的映射来实现,并且通过bloom filter来筛选出碰撞的hash,从而在后面添加字符来达到唯一性,从而解决hash碰撞

即使如此,这种方法仍然存在问题

  • 储存映射。不仅占用了储存空间,还给系统增加了额外复杂度
  • 碰撞添加字符到达唯一性。如何添加成为了问题,如果是通过一个id,递增添加,那么在高并发情况下,这可能会成为性能瓶颈(引入加锁全局id,锁会成为瓶颈;直接递增,那么一次次判断递增后的短链接是否存在也会成为瓶颈)

尽管如此,在长链接并不是特别多或者不在乎碰撞的情况下,hash方法是一个简单易行的方案

分配唯一编号

为每一个长链接唯一编号。本方法优势明显,不存在碰撞问题,也不存在为了解决碰撞,而一直递增以达到不重复的性能损失问题。但仍然存在一些问题

  • 分配编号是串行的。

    对于redis来讲,单机能支撑10w qps,性能相当高,只是要考虑到持久化;

    mysql自增机制相对来讲性能较差,但是比较简单,对于多数业务来讲完全够用

  • 仍然需要额外空间储存对应关系

  • 在分布式系统中需要更多处理来保证唯一

    这与分布式主键的处理方法一致,比如说不同子系统之间不同的初始值以及递增步伐、雪花算法、号段模式、uuid等

在选择分配唯一编号后的诸多问题

如何设计储存短链接和长链接映射的表呢?

首先要搞明白用什么类型来储存长短链接。

长链接显然不能用整数类型进行存储,只能用字符串

而对于短链接,用整数类型,储存空间更小,甚至能范围查询(虽然这样生成的唯一编号并没有太大的实际意义,用到范围查询的可能性并不高),但由于实际使用中用的一般是62进制(10个数字+2*26字母),所以还需要进行转换,如果采用字符串则少了转换过程。总的来说,采用整数类型优势更为明显。

在长短链接之后,最好还是考虑一下升级问题。比如最开始采用了mysql生成唯一编号,随着业务发展无法充分满足需求要切换到redis生成的方式,但是mysql生成又不能直接停下,因为还要生成唯一编号。这种情况下可以添加新字段source来区别生成id来源

如果要对短链接生成、访问进行追踪数据,那么储存生成时间、用户、ip等信息的字段也要添加

此外考虑到基本场景是根据短链接查询长链接,因此短链接最好建立索引。那么短链接是否可以干脆作为主键呢?一般而言,短链接是不会出现重复的,并且也不会超出最大整数范围,那么为了加快查询,添加为主键也不失为一个好的方法

如果碰到相同的长链接是否生成完全一致的短链接呢?

取决于是否要追踪数据。如果需要分析访问访问特征数据,比如访问该链接用户、ip等,那么可以将信息编码到短链接中

如果根本不需要追踪或者根本不需要通过这种方式追踪,那么就并不需要长短链接一对多生成了

短链接访问量大的时候如何优化呢?

经典老办法——加缓存。

递增编号存在可能会被遍历的问题,该如何解决呢?

  • 安全措施:限制频率,屏蔽用户、ip等
  • id稀疏:不严格按照1进行递增
  • 生成特别的id:比如采用递增id+hash(id+key)这样的方法
  • 内外分离:内部采用递增,外部生成难以找到规律的id(比如随机、hash、加密等),并储存内外映射
  • 不采用递增编号:比如uuid、雪花算法等
  • 业务分析是否是个问题:如果本来就是公开的内容,那么就算被遍历又怎么了;如果是非公开的内容,那么添加身份认证是否会更好呢?毕竟即使采用其他方法,攻击者无法通过遍历获取到内容,但也有可能从其他渠道知道链接

选择301还是302作为状态码?

301、302都是重定向状态码只是301代表永久重定向,这会直接从游览器拿缓存,这样既没有灵活性,也无法追踪。而302则代表临时重定向,也能利用缓存,显然是更优的选择

Ref

  1. https://redis.io/docs/management/optimization/benchmarks/
  2. https://www.zhihu.com/question/29270034
  3. https://juejin.cn/post/6844904090602848270
  4. https://www.v2ex.com/t/235554

你可能感兴趣的:(哲学与架构,架构)