您现在的位置是:首页 > 正文

设计短网址系统

2024-04-01 00:14:16阅读 2

链接:https://www.zhihu.com/question/29270034/answer/46446911

自增策略

通过发号,给每一个过来的长地址,发一个号即可,小型系统直接用mysql的自增索引就搞定了。如果是大型应用,可以考虑各种分布式key-value系统做发号器。不停的自增就行了。第一个使用这个服务的人得到的短地址是http://xx.xx/0 第二个是 http://xx.xx/1 第11个是 http://xx.xx/a 第依次往后,相当于实现了一个62进制的自增字段即可。

几个子问题

1. 62进制如何用数据库或者KV存储来做?

其实我们并不需要在存储中用62进制,用10进制就好了。比如第10000个长地址,我们给它的短地址对应的编号是9999,我们通过存储自增拿到9999后,再做一个10进制到62进制的转换,转成62进制数即可。这个10~62进制转换,你完全都可以自己实现。

2. 如何保证同一个长地址,每次转出来都是一样的短地址

用key-value存储,保存“最近”生成的长对短的一个对应关系。注意是“最近”,也就是说,我并不保存全量的长对短的关系,而只保存最近的。比如采用一小时过期的机制来实现LRU淘汰。这样的话,长转短的流程变成这样:
1 在这个“最近”表中查看一下,看长地址有没有对应的短地址
1.1 有就直接返回,并且将这个key-value对的过期时间再延长成一小时
1.2 如果没有,就通过发号器生成一个短地址,并且将这个“最近”表中,过期时间为1小时所以当一个地址被频繁使用,那么它会一直在这个key-value表中,总能返回当初生成那个短地址,不会出现重复的问题。如果它使用并不频繁,那么长对短的key会过期,LRU机制自动就会淘汰掉它。当然,这不能保证100%的同一个长地址一定能转出同一个短地址,比如你拿一个生僻的url,每间隔1小时来转一次,你会得到不同的短地址。但是这真的有关系吗?

3. 如何保证发号器的大并发高可用

上面设计看起来有一个单点,那就是发号器。如果做成分布式的,那么多节点要保持同步加1,多点同时写入,这个嘛,以CAP理论看,是不可能真正做到的。其实这个问题的解决非常简单,我们可以退一步考虑,我们是否可以实现两个发号器,一个发单号,一个发双号,这样就变单点为多点了?依次类推,我们可以实现1000个逻辑发号器,分别发尾号为0到999的号。每发一个号,每个发号器加1000,而不是加1。这些发号器独立工作,互不干扰即可。而且在实现上,也可以先是逻辑的,真的压力变大了,再拆分成独立的物理机器单元。1000个节点,估计对人类来说应该够用了。如果你真的还想更多,理论上也是可以的。

5. 跳转用301还是302

这也是一个有意思的话题。首先当然考察一个候选人对301和302的理解。浏览器缓存机制的理解。然后是考察他的业务经验。301是永久重定向,302是临时重定向。短地址一经生成就不会变化,所以用301是符合http语义的。同时对服务器压力也会有一定减少。
但是如果使用了301,我们就无法统计到短地址被点击的次数了。而这个点击次数是一个非常有意思的大数据分析数据源。能够分析出的东西非常非常多。所以选择302虽然会增加服务器压力,但是我想是一个更好的选择。

网站文章

  • redid过期策略_Redis数据过期策略

    1、Redis中key的的过期时间通过EXPIRE key seconds命令来设置数据的过期时间。返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间。在key上设置了过期时间后key...

    2024-04-01 00:13:51
  • 清除缓存代码_清除代码著名报价。

    清除缓存代码The phrase “software engineering” was terms at conferences organized by NATO in 1968 and 1969 ...

    2024-04-01 00:13:44
  • Flutter 实现上拉加载更多数据,下拉刷新

    Flutter 实现上拉加载更多数据,下拉刷新

    引言 昨天已经使用 RefreshIndicator 实现了下拉刷新数据的效果,今天,我们使用ScrollController来实现:上拉加载更多数据,然后再将二者汇总起来~~ 废话不多说,上菜,哦,不对,上图

    2024-04-01 00:13:37
  • Docker学习笔记(五)-Docker Compose

    Docker学习笔记(五)-Docker Compose

    背景很多应用是很复杂的,需要多个容器共同支持,任何复杂的系统可能需要启动的容器数量也很庞大,我们需要从Dockerfile build image或者docker hub拉取多个image,要创建并管理多个container,这个工作量是巨大的,docker compose应运而生。Docker Compose是什么Docker Compose帮我们启动错综复杂的容器,开发测试人员...

    2024-04-01 00:13:31
  • [Git高级教程 (一)] 通过Tag标签回退版本修复bug

    1 前言本系列之所以取名”Git高级教程”,主要是教大家解决实际工作中遇到的问题,要求读者会基本的Git用法和命令,请不要使用SourceTree这样的工具,因为它让你啥都不会、啥也不懂,git本身与Linux一脉相承,都是Linus torvalds写的嘛,所以命令行才是精髓。如果你还不会Git的话,强烈建议你学习廖雪峰的教程,简单易懂: 廖雪峰的Git教程: http://www.li

    2024-04-01 00:13:11
  • (2)机器学习任务攻略(loss太大怎么办)

    (2)机器学习任务攻略(loss太大怎么办)

    机器学习笔记

    2024-04-01 00:13:04
  • java8 stream map flatMap

    stream map flatMap

    2024-04-01 00:12:58
  • Java判断某个对象是某个类

    String s = “I AM an Object!”; boolean isObject = s instanceof Object;

    2024-04-01 00:12:31
  • Qt扫盲-QListWidget理论总结

    Qt扫盲-QListWidget理论总结

    1. 概念2. 添加列表项3. 列表其他属性4. 常用信号5. 槽函数。QListWidget 是一个继承自 QListView 的类,其实就是 QListView 的一个很经典的 列表 交互控件,在...

    2024-04-01 00:12:24
  • audio解决不能自动播放问题

    无法实现打开网页就能自动播放音乐正常情况下使用autoplay即可实现自动播放,但是现在打开网页该参数无效。

    2024-04-01 00:12:17