当前位置: 首页 > 科技观察

浅谈短链接的设计

时间:2023-03-21 22:17:55 科技观察

背景目前在很多场景下,都需要短链接,尤其是涉及到一些URL投递逻辑的时候。为什么需要短链?考虑到一个URL上有path、query等参数,将各种参数拼接在一起,形成一个短字符串。在许多社交平台上,发送的文本长度都有限制。如果URL太长,很容易被截断,那么reach就会失效。当用户收到一个短链接时,心情可能会更加愉悦:短链接就是知己知彼,百战不殆。让我们看一下短链接包含哪些信息。协议+域名+路径,协议可以直接忽略。域名是必须的(废话),而且要够短,否则就变成了长长的短链(挺傻的)。路径的最后一部分是key,看起来是一个6个字符的字符串,字符范围是大小写字母+数字。足够短的域名有什么条件?很可能足够的钱会做。涉及钱的部分这里就不深入探讨了。那么我们来研究一下这条路径的生成。Path的生成序列号哈希算法Path的获取方式之一是通过哈希算法计算得到。常见的哈希函数包括常见的加密哈希算法如MD5、SHA1,以及非加密哈希函数如HighwayHash、MurmurHash。以MurmurHash为例,已经迭代到MurmurHash3,可以生成32位和128位的哈希值,对于规律性强的key,随机分布的特性非常好。然而,哈希冲突是不可控的。虽然我们有N种方法来解决hash冲突,但是会增加整个系统的整体复杂度。自增ID也可以维护一个ID自增生成器,为每条长链生成1、2、3等自增序号,然后将长链与序号的映射保存在数据库,然后获取如https://fake.short/1、https://fake.short/2等短链接。考虑到单机容易出现单点故障,一般采用分布式ID生成器。Mysql自增假设有10台Mysql服务器,每台初始值为0...9,然后每产生一个需求就自增10,从而保证这10台Mysql服务器产生的ID是不重复。但是这种方案的缺点很明显,就是ID是可追溯的,爬虫可以顺序请求;横向扩展并不容易。比如之前约定了10台机器,那么每台机器的生产步数就是10,如果需要的话再增加一台机器就比较困难了;数据库压力还是很大的。每获取一个ID,都要对数据库进行一次读写,只能通过堆机来提高性能。基于Snowflake算法SnowFlake是Twitter采用的一种生成全球唯一ID的算法,在分布式系统中有增长趋势。第一位占1位,其值一直为0,没有实际作用。2、时间戳占41位,精确到毫秒,一共可以保存69年左右。3、工作机ID占用10位,其中高5位为数据中心ID,低5位为工作节点ID,最多可容纳1024个节点。4.序号占12位,每个节点每毫秒从0开始累加,最多累加4095个,一共可以生成4096个ID。SnowFlake算法可以在同一毫秒内生成多达1024X4096=4194304个全局唯一ID。国内也有很多基于(like)雪花算法的开源分布式唯一ID生成器:UidGenerator是百度开源的分布式UID生成器。https://github.com/baidu/uid-generatorLeafLeaf是美团开源的分布式ID生成器,可以保证全局唯一性和递增趋势,但需要依赖关系型数据库、Zookeeper等中间件。https://tech.meituan.com/2017/04/21/mt-leaf.html进一步缩短如果我们得到序列号“1536389934”,看起来还是有点长。如果要进一步缩短,可以将十进制数转换为62位基数。然后您会得到比原始序列号更短的ID。为什么要使用62位转换?62位转换是因为62位转换只包含数字+小写+大写字母。而64十六进制转换会包含/、+等符号(不符合正常url的字符)encodeURIComponent('+')=>%xx十进制转62十六进制可以缩短字符,如果我们要6个字符,已经有560亿种组合。重定向是301还是302众所周知,301是永久重定向,浏览器会缓存重定向后的地址,下次访问时不会再向原地址发起请求;按理说,通过301的重定向性能会更好,服务压力更小。但是,正因为301会缓存在浏览器中,所以服务器无法知道有多少用户通过这个短链接访问过。在当今任何数据都可以分析的时代,缺少这些数据就是失去了分析活动的能力。所以一般通过302重定向,方便记录使用的数据,稍微增加服务器的压力。(没有什么是加机器解决不了的