03 | 短 URL 生成器设计:百亿短 URL 怎样做到无冲突?
该思维导图由 AI 生成,仅供参考
需求分析
- 深入了解
- 翻译
- 解释
- 总结
设计高并发、海量数据处理的短 URL 生成器方案 本文介绍了设计一个高并发、海量数据处理的短 URL 生成器的方案。首先分析了需求和性能指标,预计每月新生成短 URL 5亿条,短 URL 总数达到120亿,对存储容量和吞吐量进行了估算。在概要设计中,提出了三种短 URL 生成算法:单项散列函数生成短 URL、自增长短 URL 和预生成短 URL。最终选择了预生成短 URL 的方案,通过离线生成并存储在文件系统中的方式,避免了冲突处理和性能问题。文章详细介绍了每种算法的优缺点,并对系统的非功能需求进行了说明,包括高可用性、高性能和短 URL 的不可猜测性。整体设计思路清晰,为读者提供了设计高并发系统的实际案例,对软件设计文档的写作也进行了指导。文章还介绍了 Fuxi 的整体部署模型,包括高并发读请求处理、预生成短 URL 存储以及访问的详细设计。文章内容丰富,涵盖了系统架构、存储、缓存、性能优化等方面,对于需要设计高并发系统的读者具有一定的参考价值。 Fuxi是一个高并发(2万QPS)、海量存储(144亿条数据)、还需要10ms的高性能平均响应时间的系统。但是Fuxi的架构并不复杂。Fuxi的业务逻辑简单,只需要完成短URL与长URL的映射关系生成与获取。开源技术体系的成熟,如HDFS集群和Redis缓存,为Fuxi提供了高可用的数据存储解决方案和短平均响应时间。文章还提出了思考题,探讨了用户重复提交同一个长URL请求生成短URL可能导致的问题以及解决方案,以及如何得到真正的并发量200的问题。 文章内容丰富,涵盖了系统架构、存储、缓存、性能优化等方面,对于需要设计高并发系统的读者具有一定的参考价值。
《李智慧 · 高并发架构实战课》,新⼈⾸单¥59
全部留言(53)
- 最新
- 精选
- 向东是大海短URL使用URL Base64 编码,其中的-和_字符显得有点突兀,特别是在开头或结尾是时。短URL使用Base62编码是否更好?
作者回复: 赞,很好的意见。
2022-02-2139 - 老码不识途再加一个架构的约束:只有2万块钱的预算 ^_^
作者回复: 大佬,请上座。
2022-02-21339 - Aibo个人感觉内存中存储短url的数据结构是不是用环形数组会好一点. 短url的场景下,使用链表会有两个缺点 1. gc压力大,频繁申请内存空间 2.格外的指针开销,短url才6byte,指针就占1byte,也就是内存中10g数据1个多g都是指针
作者回复: 赞,非常好的建议
2022-03-05632 - Spark对自增长短 URL可以进行如下优化: 在设计的短链接的时候采用这样的方法: 根据自增主键id将前面补0(4位短链接补至7位,6位短链接补至10位,8位短链接补至14位)如主键:123,补0至0000123 倒转补完0之后的id,如3210000 将倒转之后的短链接十进制转62进制。将3210000转62进制 本质上来讲,因为用户不知道你补位的位数,所以无法反推出你之前的短链接与之后的短链接。 在自增的选择上,可以选择redis的自增机制。 是不是这样,我也可以满足并发的需求,毕竟计算速度远大于查找。 同时,清理的过程也更加简单,只需要在达到自增补位上限的时候,将自增变为1重新发号即可 当然,从技术上讲,他是可预测的,毕竟短链就这么多位,猜测(7-14进行枚举),但是面对大部分业务来说,他已经满足部分不可预测的需求。
作者回复: 很赞
2022-02-22628 - Jialin问题一:如何解决相同的原始链接生成不同的短链接? 当要给一个原始网址生成短网址的时候,我们要先拿原始网址在数据库中查找,看数据库中是否已经存在相同的原始网址了。如果数据库中存在,那我们就取出对应的短网址,直接返回给用户。并给短网址和原始网址这两个字段,都添加索引。短网址上加索引是为了提高用户查询短网址对应的原始网页的速度,原始网址上加索引是为了加快通过原始网址查询短网址的速度。 问题二:并发量是如何计算的? 基于利特尔法则(Little's law)得知,并发度 = QPS * 平均耗时,所以,2 万 QPS,10ms 平均响应时间,真正的并发量只有 200。
作者回复: 1 索引的代价有点大的,我们再考虑下 2 是的
2022-02-21715 - Mew151第1个问题,还可以从另外一个角度考虑:即客户端本地记用户请求过的长-短URL映射,如果用户再次请求同一个长URL,先查客户端本地映射,如果有就直接返回。这种方式能防住大部分正常的客户端重复请求,防不住的是例如恶意攻击者直接抓包调接口,因此服务端的判重还得做。
作者回复: 赞
2022-03-0912 - 雪碧心拔凉看了下评论区的,大部分都是通过布隆过滤器来解决不能重复,有一下几个疑惑点。 1、已使用的数据还会被回收,因此布隆过滤器的数据还存在删除的操作,或者每次回收时重构布隆过滤器? 2、布隆过滤器本身有一定的误判率,如果存在,但是实际可能不存在,这时要走生成的逻辑,请求耗时可能大于10ms。当然这个可以通过调整布隆过滤器的参数降低概率 我理解是不是只需要保持一段时间内不重复即可,是否可以把长url(做个md5,降低存储?)和短url存储在缓存(如redis)中,有效期设为一天或者半天,这样能控制一段时间内返回同一个短url即可?
作者回复: 赞同
2022-05-1010 - 极客加载到预加载短 URL 服务器的 1 万个短 URL 会以链表的方式存储,每使用一个短 URL,链表头指针就向后移动一位,并设置前一个链表元素的 next 对象为 null。这样用过的短 URL 对象可以被垃圾回收。当剩余链表长度不足 2000 的时候,触发一个异步线程,从文件中加载 1 万个新的短 URL,并链接到链表的尾部 ----- 这里如果为了高可用是不是需要保存到日志或者redis,要是服务有bug导致频繁重启,那么重启后又要获取1万个。多来几次会浪费很多短地址没有使用。且预生成的144亿次没有继续生成的机制保证。
作者回复: 预生成多20%的冗余,一般重启丢失一些是可以接受的,频繁重启可能系统有大麻烦了,需要另外思考了。 继续生成机制可以在系统运行期考虑,如果短URL消耗快于预期,可以增加再生成机制。架构不必一步到位。
2022-02-21410 - Steven思考题: 1,首先可以明确,一定程度上的重复生成是可以的。 方案一:可以考虑用布隆过滤器; 方案二:考虑Redis中存储长链接 -> 短链接,并设定合理的过期时间,参考课程内容,貌似可以6天,或许1小时就可以。 另外,基于分布式ID生成短URL也是可以的。 2,200 = 20000 * 0.01 问题:“对于这样简单的业务逻辑以及 200 这样的并发压力,我们使用配置高一点的服务器的话,只需要一台短 URL 服务器其实就可以满足了。”,大概是一台什么配置的服务器?
作者回复: 思考题:赞 市面上标配的高CPU物理机就可以了。其实可能都不用高配,随便什么服务器都够用了,主要是开发的时候响应时间要能做到10ms。
2022-03-0328 - cy_walker老师,我有个疑问。就是在生成短链的时候,假如在短时间内有大量需要生成短链的请求,那预先加载的1W个短链就不够了,这种情况该如何解决?直接服务降级?
作者回复: 1 预加载短URL的线程是异步执行的,短URL少于2000就会加载,加载时间顺利的话几十毫秒,这个响应速度应该是能够满足高并发的。 2 预加载短URL服务器也是集群部署的,每台服务器预加载1万个。 3 如果并发超过以上两点的处理能力,需要限流。
2022-03-0228