短网址系统

文章目录

    • 1. 短网址服务整体介绍
    • 2. 如何通过哈希算法生成短网址?
      • 2.1 如何让短网址更短
      • 2.2 如何解决哈希冲突?
      • 2.3 如何优化哈希算法生成短网址的性能?
    • 3. 如何通过ID生成器生成短网址?
      • 3.1 相同的原始网址可能会对应不同的短网址
      • 3.2 如何实现高性能的 ID 生成器?
    • 4. 总结

在微博里发布一条带网址的信息,微博会把里面的网址转化成一个更短的网址。只要访问这个短网址,就相当于访问原始的网址。

原始网址:https://github.com/wangzheng0822/ratelimiter4j
短网址:http://t.cn/EtR9QEG

1. 短网址服务整体介绍

当用户点击短网址时,短网址服务会将浏览器重定向为原始网址。这个过程是如何实现的呢?
在这里插入图片描述
从图中可看出,浏览器会先访问短网址服务,通过短网址获取到原始网址,再通过原始网址访问到页面。这部分功能今天不讲。重点来看,如何将长网址转化成短网址?

2. 如何通过哈希算法生成短网址?

哈希算法可以将一个不管多长的字符串,转化成一个长度固定的哈希值

在生成短网址这个问题上,我们不需要考虑反向解密的难度,只需关心哈希算法的计算速度和冲突概率。

比较著名并且应用广泛的一个哈希算法,那就是 MurmurHash 算法。尽管这个哈希算法在2008年才被发明出来,但现在它已经广泛应用到Redis、MemCache、Cassandra、HBase、Lucene等众多著名的软件中。

MurmurHash 算法提供了两种长度的哈希值,一种是32bits,一种是128bits。为了让最终生成的短网址尽可能短,可以选择32bits的哈希值。对于开头那个GitHub网址,经过MurmurHash 计算后,得到的哈希值就是181338494。我们再拼上短网址服务的域名,就变成了最终的短网址 http://t.cn/181338494(其中,http://t.cn是短网址服务的域名)。

2.1 如何让短网址更短

通过MurmurHash 算法得到的短网址还是很长,而且跟开头那个网址的格式好像也不一样。

我们将10进制的哈希值,转化成更高进制的哈希值,这样哈希值就变短了。我们知道16进制中,我们用A~E 来表示10~15。在网址URL中,常用的合法字符有0~9、a~z,A ~ Z 这样62个字符。为了让哈希值表示起来尽可能短,可以将10进制的哈希值转化成62进制。计算过程如下。最终用62进制表示的短网址就是http://t.cn/cgSqq。
在这里插入图片描述

2.2 如何解决哈希冲突?

尽管 MurmurHash 算法,冲突概率非常低。一旦冲突,会导致两个原始网址被转化成同一个短网址。当用户访问短网址时,就无从判断,想要访问的是哪一个。这个问题该如何解决呢?

一般情况下,我们会保存短网址跟原始网址之间的对应关系,以便后续用户在访问短网址的时候,可以根据对应关系,查找到原始网址。存储这种对应关系的方式有很多,比如自己设计存储系统或者利用现成的数据库。前面我们讲到的数据库有MySQL、Redis。就拿MySQL来举例。假设短网址与原始网址之间的对应关系,就存储在MySQL 数据库中。

当有一个新的原始网址需要生成短网址的时候,先利用MurmurHash 算法,生成短网址。然后,拿这个新生成的短网址,在MySQL 数据库中查找。

  • 如果没有找到相同的短网址,表明,这个新生成的短网址没有冲突。于是我们就将这个短网址返回给用户(请求生成短网址的用户),然后将这个短网址与原始网址之间的对应关系,存储到MySQL数据库中。

  • 如果找到了相同的短网址,那也并不一定说明就冲突了。我们从数据库中,将这个短网址对应的原始网址也取出来。

    • 如果数据库中记录的原始网址,跟正在处理的原始网址一样,说明已经有人请求过这个原始网址的短网址了。就可以拿这个短网址直接用。
    • 如果数据库中记录的原始网址,跟正在处理的原始网址不一样,说明哈希算法发生了冲突。不同的原始网址,经过计算,得到的短网址重复了。这个时候,怎么办?

    可以给原始网址拼接一串特殊字符,比如“[DUPLICATED]",然后再重新计算哈希值,两次哈希计算都冲突的概率,显然是非常低的。
    假设出现非常极端的情况,又发生冲突了,我们可以再换一个拼接字符串,比如“[OHMYGOD]",再计算哈希值。然后把计算得到的哈希值,跟原始网址拼接了特殊字符串之后的文本,一并存储在MySQL数据库中。

    当用户访问短网址的时候,短网址服务先通过短网址,在数据库中查找到对应的原始网址。如果原始网址有拼接特殊字符(这个很容易通过字符串匹配算法找到),我们就先将特殊字符去掉,然后再将不包含特殊字符的原始网址返回给浏览器。

2.3 如何优化哈希算法生成短网址的性能?

为了判断生成的短网址是否冲突,需要拿生成的短网址,在数据库中查找。如果数据库数据非常多,查找会非常慢,影响短网址服务的性能。如何优化?

  • 可以给短网址字段添加B+树索引。这样通过短网址查询原始网址的速度就提高了。
  • 在短网址生成的过程中,我们会跟数据库打两次交道,也就是会执行两条SQL语句。第一个SQL 语句是通过短网址查询短网址与原始网址的对应关系,第二个SQL语句是将新生成的短网址和原始网址之间的对应关系存储到数据库。

我们知道,一般情况下,数据库和应用服务(只做计算不存储数据的业务逻辑部分)会部署在两个独立的服务器或者虚拟服务器上。那两条SQL 语句的执行就需要两次网络通信。这种IO通信耗时以及SQL 语句的执行,才是整个短网址服务的性能瓶颈所在。所以,为了提高性能需要尽量减少SQL 语句。如何减少SQL 语句呢?

  • 可以给数据库中的短网址字段,添加一个唯一索引(不止是索引,还要求表中不能有重复的数据)。当有新的原始网址需要生成短网址的时候,我们并不会先拿生成的短网址,在数据库中查找判重,而是直接将生成的短网址与对应的原始网址,尝试存储到数据库中。如果数据库能够将数据正常写入,那说明并没有违反唯一索引,也就是说,这个新生成的短网址并没有冲突。
  • 如果数据库反馈违反唯一性索引异常,那还得重新执行刚刚讲过的“查询、写入”过程,SQL语句执行的次数不减反增。但是,在大部分情况下,我们把新生成的短网址和对应的原始网址,插入到数据库的时候,并不会出现冲突。所以,大部分情况下,只需要执行一条写入的SQL语句就可以了。所以,从整体上看,总的SQL语句执行次数会大大减少。

我们还有另外一个优化SQL语句次数的方法,那就是借助布隆过滤器

  • 把已经生成的短网址,构建成布隆过滤器。我们知道,布隆过滤器是比较节省内存的一种存储结构,长度是10亿的布隆过滤器,也只需要125MB左右的内存。

  • 当有新的短网址生成的时候,先拿这个新生成的短网址,在布隆过滤器中查找。如果查找不存在,说明这个新生成的短网址没有冲突。再执行写入短网址和对应原始网页的SQL语句就可以了。通过先查询布隆过滤器,总的SQL语句的执行次数减少了

3. 如何通过ID生成器生成短网址?

可以维护一个ID自增生成器。它可以生成1、2、3…这样自增的整数ID。当短网址服务接收到一个原始网址转化成短网址的请求之后,它先从ID生成器中取一个号码,然后将其转化成62进制表示法,拼接到短网址服务的域名(比如http://t.cn/)后面,就形成了最终的短网址。最后,我们还是会把生成的短网址和对应的原始网址存储到数据库中。

理论非常简单好理解。有几个细节需要处理。

3.1 相同的原始网址可能会对应不同的短网址

每次新来一个原始网址,就生成一个新的短网址,会导致两个相同的原始网址生成了不同的短网址。如何处理呢?

  • 第一种思路是不做处理。相同的原始网址对应不同的短网址,用户是可以接受的。用户只关心短网址能否正确地跳转到原始网址。短网址长什么样,他根本就不关心。

  • 第二种思路是借助哈希算法生成短网址的处理思想,当要给一个原始网址生成短网址的时候,要先拿原始网址在数据库中查找,看数据库中是否已经存在相同的原始网址了。如果数据库中存在,那我们就取出对应的短网址,直接返回给用户。
    不过,这种处理思路有个问题,我们需要给数据库中的短网址和原始网址这两个字段,都添加索引。短网址上加索引是为了提高用户查询短网址对应的原始网页的速度,原始网址上加索引是为了加快刚刚讲的通过原始网址查询短网址的速度。这种解决思路虽然能满足“相同原始网址对应相同短网址”这样一个需求,但是是有代价的:一方面两个索引会占用更多的存储空间,另一方面索引还会导致插入、删除等操作性能的下降。

3.2 如何实现高性能的 ID 生成器?

实现ID生成器的方法有很多,比如利用数据库自增字段。当然我们也可以自己维护一个计数器,不停地加一加一。但是,一个计数器来应对频繁的短网址生成请求,显然是有点吃力的(因为计数器必须保证生成的ID不重复,笼统概念上讲,就是需要加锁)。如何提高ID生成器的性能呢?

  • 第一种思路,可以给ID生成器装多个前置发号器。我们批量地给每个前置发号器发送ID号码。当我们接受到短网址生成请求的时候,就选择一个前置发号器来取号码。这样通过多个前置发号器,明显提高了并发发号的能力
    在这里插入图片描述
  • 第二种思路跟第一种差不多。不再使用一个ID生成器和多个前置发号器这样的架构,直接实现多个ID生成器同时服务。为了保证每个ID生成器生成的ID不重复。我们要求每个ID生成器按照一定的规则,来生成ID号码。比如,第一个ID生成器只能生成尾号为0的,第二个只能生成尾号为1的,以此类推。通过多个ID生成器同时工作,也提高了ID生成的效率
    在这里插入图片描述

4. 总结

短网址服务的两种实现方法。

通过哈希算法生成短网址。采用计算速度快、冲突概率小的MurmurHash算法,并将计算得到的10进制数,转化成62进制表示法,进一步缩短短网址的长度。对于哈希算法的哈希冲突问题,通过给原始网址添加特殊前缀字符,重新计算哈希值的方法来解决。

通过ID生成器生成短网址。维护一个ID自增的ID生成器,给每个原始网址分配一个ID号码,并且同样转成62进制表示法,拼接到短网址服务的域名之后,形成最终的短网址。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/479954.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个神经元的价值和一个神经病的坚持

作者 | 周博磊来源 | 机器之心一个神经元能够催生多少故事?香港中文大学信息工程系助理教授周博磊近日撰文介绍了他自 2015 年开始至今对神经元的研究经历。最近,他与 David Bau、朱俊彦等人合作的神经元研究论文发表在了 PNAS 杂志上。以下是周博磊的原…

直通BAT必考题系列:深入剖析JVM之G1收集器、及回收流程、与推荐用例

金三银四马上到了,即将进入面试的高峰期。在BAT面试中,JVM基本都是必考的系列。你至少需要掌握JVM内存模型与JVM参数详细配置,JVM的4种垃圾回收算法、垃圾回收机制与总结,以及今天重点谈到的JVM垃圾回收算法的实现:JVM…

多任务学习方法

最近一直在做多任务,但是效果好象没什么提升,因为都是凭自己的想法和感觉在做。于是上网查找了一些这方面的资料,寻求一些理论上的支撑和前人经验上的帮助。 多任务学习: 故名思意,就是多个任务一起学习。为什么要进行…

曹羽 | 从知识工程到知识图谱全面回顾

本文转载自公众号:集智俱乐部。文本挖掘和图形数据库 | ©ontotext导语知识工程是符号主义人工智能的典型代表,近年来越来越火的知识图谱,就是新一代的知识工程技术。知识工程将如何影响未来人工智能领域的发展,甚至让计算机拥…

4大JVM性能分析工具详解,及内存泄漏分析方案

谈到性能优化分析一般会涉及到: Java代码层面的,典型的循环嵌套等 还会涉及到Java JVM:内存泄漏溢出等 MySQL数据库优化:分库分表、慢查询、长事务的优化等 阿里P8架构师谈:MySQL慢查询优化、索引优化、以及表等优化…

从 0 搭建一个工业级推荐系统

推荐系统从来没像现在这样,影响着我们的生活。当你上网购物时,天猫、京东会为你推荐商品;想了解资讯,头条、知乎会为你准备感兴趣的新闻和知识;想消遣放松,抖音、快手会为你奉上让你欲罢不能的短视频。而驱…

论文浅尝 | 虚拟知识图谱:软件系统和应用案例综述

本文转载自公众号:DI数据智能。Virtual Knowledge Graphs: An Overview of Systems and Use Cases作者:Guohui Xiao, Linfang Ding, Benjamin Cogrel & Diego Calvanese供稿:Guohui Xiao编者按:Data Intelligence 发表意大利博…

LeetCode 169. 求众数(摩尔投票)

文章目录1. 题目信息2. 解题思路3. 代码3.1 排序3.2 map计数3.3 摩尔投票1. 题目信息 给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在众数。 示例 1:输入…

阿里P8架构师谈:JVM的内存分配、运行原理、回收算法机制

不管是BAT面试,还是工作实践中的JVM调优以及参数设置,或者内存溢出检测等,都需要涉及到Java虚拟机的内存模型、内存分配,以及回收算法机制等,这些都是必考、必会技能。 JVM内存模型 JVM内存模型可以分为两个部分&…

我的BERT!改改字典,让BERT安全提速不掉分(已开源)

文 | 苏剑林编 | 小轶背景当前,大部分中文预训练模型都是以字为基本单位的,也就是说中文语句会被拆分为一个个字。中文也有一些多粒度的语言模型,比如创新工场的ZEN和字节跳动的AMBERT,但这类模型的基本单位还是字,只不…

2020年考证时间表汇总!这些证书值得拥有!

原文地址: https://zhuanlan.zhihu.com/p/100824416 2020年考证时间表汇总!这些证书值得拥有!已认证的官方帐号154 人赞同了该文章昨日之日不可留,2019年已然过去,2020年的我们不能再一成不变!快根据自身情…

征稿 | 2019年全国知识图谱与语义计算大会(CCKS2019)第二轮征稿启事

2019年全国知识图谱与语义计算大会China Conference on Knowledge Graph and Semantic Computing (CCKS 2019)2019年8月24日-27日,杭州征稿截止: 2019年5月18日全国知识图谱与语义计算大会(CCKS: China Conference on Knowledge Graph and Semantic Comp…

直通BAT必考题系列:JVM的4种垃圾回收算法、垃圾回收机制与总结

BAT必考JVM系列专题 直通BAT必考题系列:深入详解JVM内存模型与JVM参数详细配置 垃圾回收算法 1.标记清除 标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。 在标记阶段首先通过根节点(GC Roots),标记所…

遗传算法及其应用实现

使用遗传算法求解函数具有最大值的点X """ Visualize Genetic Algorithm to find a maximum point in a function. """ import numpy as np import matplotlib.pyplot as pltDNA_SIZE 10 # DNA length POP_SIZE 100 # population size CROSS…

论文浅尝 | 一种嵌入效率极高的 node embedding 方式

论文笔记整理:叶群,浙江大学计算机学院,知识图谱、NLP方向。会议:WSDM 2019链接:https://dl.acm.org/citation.cfm?id3290961Motivation基于spring-electrical的模型在网络可视化中取得了非常成功的应用,一…

重要的,是那些训练中被多次遗忘的样本

文 | kid丶源 | 知乎编 | 兔子酱今天跟大家分享一篇很有意思的文章,是一篇探讨深度学习模型记忆&遗忘机制的文章,是一篇角度很新颖的题材,同时又有一定启发作用。这篇文章发表在深度学习顶会ICLR19,标题是《An empirical stud…

直通BAT必考题系列:7种JVM垃圾收集器特点,优劣势、及使用场景

直通BAT之JVM系列 直通BAT必考题系列:JVM的4种垃圾回收算法、垃圾回收机制与总结 直通BAT必考题系列:深入详解JVM内存模型与JVM参数详细配置 今天继续JVM的垃圾回收器详解,如果说垃圾收集算法是JVM内存回收的方法论,那么垃圾收集…

模拟嫁接技术

模拟嫁接技术:定义嫁接算子及策略剪接算子及策略GPOGA算法总结定义 收益和代价 对一棵生成树 T1,若将某结点的一条分枝移至另一结点作为其一条分枝后产生的生成树为 T2,考察分枝移动前后生成树的边长和的变化,则定义收益(gain)和…

HuggingFace又出炼丹神器!稀疏矩阵运算进入平民化时代!

文 | rumor酱编 | YY一提到模型加速,大家首先想到的就是蒸馏、(结构性)剪枝、量化(FP16),然而稀疏矩阵(sparse matrix)运算一直不被大家青睐。原因也很简单,一是手边没有…

章乐焱 | 用“科技”监管“科技”,知识图谱能做什么?

本文转载自公众号:恒生技术之眼。人工智能、大数据等前沿科技的爆发,推动金融科技进入了一个崭新的时代,也成为监管科技发展的重要推动力。在这个Fintech的黄金时代,前沿科技正在如何赋能监管?这方面,恒生公…