短网址服务设计

短网址服务设计

背景

短网址服务,用来将输入的一个长网址转换为一个短网址(比如附录中的案例),当用户请求这个短网址时,服务查询出真实的url;
设计这么一个短网址服务,需要考虑哪些点?

数据结构

首先,需要考虑短网址应该如何存储,使用一个key-value结构就可以;
key是生成的短网址,具有唯一性;
value为原始真实网址;

算法

计算短网址的算法可以很简单,短网址与原始网址就只存在一个映射关系。
从1开始递增来映射每一个网址;
1个位上可以使用26位字母+10个数字,即36进制; 而如果也用上大写字母,就是62进制;
当然,在计算前需要通过value来查一遍,确定是否有重复键,如果有重复,直接返回;
那通过value如何快速定位是否有重复?再使用一个STL set来解决判重是个方法,有没有更好的方式?

使用一个hash表或STL set保存所有的长url会消耗很大的空间;而如果不保存这个映射关系,用户针对同一个长url的多次请求都返回的是不同的短url,体验不好,也消耗短url资源;
好的做法:保存最近一段时间(比如6小时)的长url记录,这段时间内,对同一长url的转换,返回的是同一个短url;而过期之后再做转换,返回另一个新的URL;

 

确定key的长度和value的长度

value长度可以设置在500,一般的网址不会超过这个数;
key: t.cn/**
key的长度决定了能够支持多少个短网址;
如果是5位长度,能够支持6000多万的网址,6位长度就是21亿;

数据容量

预估数据容量
会占用多大的空间;对于这类服务,基于效率考虑,一般是全内存操作;
如果单机能够装下,使用单机;
如果单机无法装下,需要分片;分片策略可以根据key的递增范围来定,也可以根据取模来确定;

分片策略

根据key的递增范围分片

优点: 扩容简单,超过1个服务器的容量后就增加一台机器;
缺点:负载可能不均衡;一般后生成的短网址访问比较频繁,造成装载早期短网址的服务器空闲;

根据key的取模来分片

优点:用户的负载比较均衡;
缺点:难以扩容

取舍:可以先预估数据容量,确定使用的服务器数,使用第二种分片方法;当数据超出预估的容量,对于超出的key再使用第一种分片方法路由到新的服务器上(打补丁)

接口设计

确定用户传入的接口协议,用户的输入和输出

并发读写和数据存储

使用什么来存放这些key-value数据?
貌似一个STL hash map容器就可以,但map不是线程安全的,考虑加锁?
如果实时性要求不高,可以使用AB两块内存操作,一块内存线上读,一块线下写,定期更新;
由于用户输入了长的网址之后,需要在终端上能够显示出被转换的短网址,所有对写的实时性也是有要求的;
要求实时,针对map可能得用上锁,或者直接使用第三方内存产品,如redis,memcache等;
对redis的读写使用异步进一步提高并发效率;

网络

对于用户请求量,如果是千兆网能够满足,使用一个单线程事件循环来处理;(IO non-blocking + io multiplexing)
如果用户请求更大,使用多个Reactor事件循环来处理,接入的reactor只负责事件的监听,连接建立后,将用户请求的处理转到后续的计算reactor中处理;
查询和更新逻辑简单,可以直接在IO事件循环中处理(类似ngnix架构)
如果更新逻辑复杂,考虑后台增加额外的进程/线程池,处理异步写操作;

安全

(可选)考虑有恶意用户,构造不存在的网址来连续触发请求,以此来占满短网址的id;
可对网址进行合法性校验(直接访问那个网址太耗时间,不太显示)
对同一来源用户限制请求数;

案例

http://t.im/ 这个短网址生成器上使用的就是36进制递增来做的:
例如,多次输入不同的长网址,得到的短网址:
http://t.im/vgu8
http://t.im/vgu9
http://t.im/vgu0
http://t.im/vgua
从这也可看出这个网站的并发并不大,我这几次请求都是相隔几秒的;
这个网站也没有做特殊的网址校验规则,比如输入a.bb.ccc之类的网址,都为合法;

 

后记

以上是自己的一些想看,看过网上的一些文章后,发现有不少改进的地方:

1. 短url的存储

设计时使用的是字母和数字的组合,使用36进制或62进制是为了让url尽可能的短;在后台存储的时候,使用整型更为合适,
整型比较比字符串比较要高效,像redis等第三方产品对整型的查找都有专门的优化;后台整型存储,返回给用户时,进行10进制到36进制的转换即可;

 

2. 分布式发号器
自增的发号器是单点。如果流量大了,涉及到拆分,分成多个服务器来处理;发号器同样可以扩容到多个,扩到2台,分别发单双号;第一台发单号,第二天发双号,不会重复;而扩容到10台,则分别发0~9尾号的号;

 

Posted by: 大CC | 06NOV,2015
博客:blog.me115.com [订阅]
Github:大CC

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

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

相关文章

我抓到bit哥了,嘿嘿嘿(5)

作者简介 作者名:1_bit 简介:CSDN博客专家,2020年博客之星TOP5,蓝桥签约作者。15-16年曾在网上直播,带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息,迷茫的你会找到答案。 目录 HTML基…

遥感、地理空间数据、全国基础数据下载网站大全汇总

本文收集整理了国内外常用的遥感、GNSS、地理空间数据下载网站,可以下载各种格式的矢量、栅格等数据,主要包括遥感影像、NDVI、太阳辐射、数字高程模型等各种地理空间数据,供GISer学习交流使用。 1. 地理空间数据云 该网站为国内学者使用最多的、数据下载方便的网站,可以…

RPA之基于FlaUI的微信发送消息给某人

本文由网友蓝创精英团队投稿,欢迎转载、分享原文作者:蓝创精英团队原文链接:https://kesshei.blog.csdn.net/article/details/124955177目的一直想实现微信的群发功能,但是,没有实现,原因有一条是怕违法&am…

Android之通过文件绝对路径获取音视频的时长和视频的缩略图

1 需求 遍历一个文件夹,需要获取音视频的时长和视频的第一帧图像 2 关键代码实现 获取本地音视频的时长(这里计算出来的是秒为单位),如果文件不是音视频,下面的函数会发生异常,也就是返回0,我们除了通过文件头来判断这个文件是音视频之后,然后再获取这个文件的时长,如…

1.8-zabbix服务端安装

zabbix 是另外一个用的比较多地监控工具,同样也需要 apachephp 的支持,但它比nagios 要多一个 mysql,因为它有数据需要存储。所以,安装 zabbix,必须要安装 mysql。cacti、nagios、zabbix都是用php写的网页,…

感受机房管理化繁为简-新款KVM使用心得

感受机房管理化繁为简-新款KVM使用心得 一、 背景 随着网络应用的不断增多,各地机房服务器数量也随之增加,利用多传统主机切换器的方式已经无法满足目前这种区域广、设备多人员紧缺的现状,而且即使是使用了一些远程管理软件,实现的…

我化身保姆为你提供 html 教学服务(6)

作者简介 作者名:1_bit 简介:CSDN博客专家,2020年博客之星TOP5,蓝桥签约作者。15-16年曾在网上直播,带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息,迷茫的你会找到答案。 目录 HTML基…

那一年,我考入了西北师范大学GIS专业,然而我很迷茫,GISer的职业规划到底是怎样的?

那一年,我考入了西北师范大学,录取专业为地理信息系统,也就是常说的GIS,本科毕业后又考取了GIS专业的研究生,顺利毕业,进入了高校从事GIS教育工作。作为一个GISer,我相信有很多人跟我一样很迷茫…

Python自动化之语法基础

1 第一个程序 hello world 在Linux环境下执行 vim hello.py #!/usr/bin/env python #指定解释器 print("hello world") 运行Python程序 Python hello.py 第一行是指定解释器,另一种写法是#!/usr/bin/python,后者限制了Python的位置&#x…

jquery分页插件

jquery.mypagination.js 文件: /* * * * jquery分页插件* 1.0 zheng 2014-03-18 * 1.1 兼容url包含#号地址,GoToPage可以指定锚点(特殊需求)2014-04-10 09:00:34* 1.2 可以配置分页条列出页面数* 1.3 增加了页面码跳转功能* …

Android之如何分析手机系统相册图片和视频删除后保存的位置

1 需求 需要获取各种型号手机系统相册图片和视频删除后保存的位置 2 分析 1)我们可以通过在sdcard目录下进行相关查找文件夹关键字,对 "cycle"或者"trash"或者*galle*进行忽略大小写模糊查询都有文件夹 find . -iname *cycle* find . -iname *trash*…

WPF 实现水珠效果按钮组

本文经原作者授权以原创方式二次分享,欢迎转载、分享。原文作者:普通的地球人原文地址:https://www.cnblogs.com/tsliwei/p/8041928.html相关知识这部分基本就是废话,网上都能找到,我只不过是整理了以下.建议先不看,用到的时候可以回来看看贝…

GetDisplayName 获取枚举的显示值

item.State.GetDisplayName(), 转载于:https://www.cnblogs.com/zhongku/p/4944315.html

组策略管理——软件限制策略(4)

编写软件限制规则 在前面几篇文章中讲了软件限制规则的基本概念,现在就来学习如何编写自定义软件限制策略。 编写规则应遵循的原则 首先,需要大家注意的是,软件限制策略应本着方便、安全、实用的原则来编写。限制规则灵活方便,自定…

我使用 html 反向输出自己打自己(7)

作者简介 作者名:1_bit 简介:CSDN博客专家,2020年博客之星TOP5,蓝桥签约作者。15-16年曾在网上直播,带领一批程序小白走上程序员之路。欢迎各位小白加我咨询我相关信息,迷茫的你会找到答案。 目录 HTML基…

甘肃省普通高等学校高职(专科)升本科考试英语科考试大纲(试行)

甘肃省普通高等学校高职(专科)升本科考试英语科考试大纲(试行) 一、考试目的 全面考核普通高等学校高职(专科)应届毕业生英语课程是否达到教学大纲所规定的目标(领会式掌握3500单词&#xff0c…

256种编程语言大荟萃

本文是码农网原创翻译,转载请看清文末的转载要求,谢谢合作! 双休日常常意味着很多休息时间。与其懒洋洋地坐在那里玩游戏,为何不学点新知识武装自己?本文中不会特定推荐哪种编程语言,但是会提供基于GitHub上…

java 获取系统当前时间

Calendar ca Calendar.getInstance(); int year ca.get(Calendar.YEAR);//获取年份 int monthca.get(Calendar.MONTH);//获取月份 int dayca.get(Calendar.DATE);//获取日 int minuteca.get(Calendar.MINUTE);//分 int hourca.get(Calendar.HOUR)…

Android之最简单的遍历某个目录下的所有文件(递归)

1、问题 遍历某个目录下的所有问题文件 2、代码实现 fun getRecoverTrashFile(path: String) {if (TextUtils.isEmpty(path))returntry {var file File(path)if (file null || !file.exists()) {return}var files file.listFiles()if (files null || files.size < 0) {…

Castle.DynamicProxy拦截器

在asp.net mvc或asp.net miniapi中&#xff0c;有过滤器&#xff0c;可以在请求前或后增加一层&#xff0c;达到验证&#xff0c;过滤等作用&#xff0c;如果在Service的方法前后加一层呢&#xff1f;这里介绍一下Castle.DynamicProxy的用法。首先引入Castle.Core实现代码相对轻…