[Markdown阅读][1]

今天上班的时候收到一个需要短链接的需求,之前的做法都是使用了新浪的短链接API(https://api.weibo.com/2/short_url/shorten.json)。但一是外网访问,二可能是新浪有所限制(毕竟是免费的),性能肯定不是太好。于是就想能不能自己实现一个,这样内网访问肯定快不少。

下班在班车上想了下,初步有些思路,记录一下,有什么说错的,欢迎指正。关于短链接的问题,我首先想到是两个问题:

 1. 持久化的问题,是否有必要保证短链接永久有效?
2. 碰撞的问题,如何保证所有长链接对应的短链接是唯一的? 第一个问题我想如果能有一个算法直接对`url`本身进行计算然后得到一个短链接,而且是可逆那么这个问题就不存在了,但稍微一想就知道这个不大现实,比如类似md5这样的摘要算法,一是不可逆,必然还是需要存储一个映射关系的,二为了“短”,第2个问题肯定会更加突出。 此路不通,我想肯定还是得引入`DB`的,因为平时项目中使用`Redis`比较多,直觉它比较合适。对于存储这种映射关系,`NoSQL`最合适不过了。而且`Redis`数据结构灵活,API简单明了,性能也很不错。开启`EOF`后,持久化问题也能得到保证,另外`Redis`支持过期,可以满足一些特殊的需求。 再来看性能问题(初衷就是想提高性能的)。个人觉得要提高性能,如何解决第2个问题是关键。我有一个思路相信也是大家都能想到的:“提前计算”和“缓存”,说就是`先计算好一批短链接缓存起来,请求过来直接取就可以了`。这里大概还有以下几个问题: 1. 怎么保证缓存起来的短链接都是各不相同的?
2. 怎么保证缓存起来的跟历史生成的不相同?
3. 怎么保证供大于求? 第1个问题,应该比较简单,编码应该是能解决的。第2个问题我考虑两个方面: 1)短链接的基数必须足够大。
参考新浪短链接http://t.cn/RhCtEye,6位字符,取值范围在[a-zA-Z0-9],那么基数就是`56,800,235,584`,56亿多应该说是足够大的了。那么就要看`随机算法`,只要足够随机,那么两次重复的概率就很小了。 2)以防万一,每次都去做一次check,按照上面的想法,生成的短链接映射关系都是存储在`Redis`中的,只要一次`get`就可以了。`get`的时间复杂度为[O(1)][1],只要保证数据都在内存里是非常快的(加上内网访问)。 第2)点在非常高的并发下还是有问题的,可能存在`get`的时候一个相同的key刚好还没`set`的进来,但结合第1)点这种可能性应该说是非常非常小了,而且我们实际的并发也不是特别大,所以忽略不计。 第3个问题更多是设计上的考虑。我的想法是用一个阻塞队列来实现,综合前面的问题,那应该就是一个去重的阻塞队列。至于如何保证“供大于求”,那就得根据前端的压力来调整队列的大小了。 这里还有一个问题,就是相同的url生成短链接的问题,如果要保证相同的url只对应一个短链接,那就得每次生成之前要去`Redis`找回一下(批量可以`mget`[O(N)][2]),增加了性能损耗,但是当这种情况很多的时候,比如恶意请求,那么反而会更好。可以作为可选配置。 上面说的都是短链接生成的问题,短链接重定向也就是还原到原始链接相对简单,一个`get`操作就可以搞定了,如果为了提高性能,减少不必要的`Redis`访问,可以在应用层增加一层Cache,比如`LRU Cache`。 最后说下存在的瓶颈: 1. 短链接的随机生成算法,`java.util.Random`貌似不是非常靠谱;
2. 去重的阻塞队列,这个应该是最大的瓶颈,如果一个队列,并发性能就很容易受限于此,如果搞多个,那么碰撞的问题就比较棘手;
3. Redis的性能。其实这里Redis可以换成任何其他类似的`NoSQL`产品。 好了,把脑子里想的写完了,感觉实际应该够用了。有问题欢迎拍砖。 [1]: https://www.zybuluo.com/zhanjindong/note/34734
[2]: http://redis.readthedocs.org/en/latest/string/get.html
[3]: http://redis.readthedocs.org/en/latest/string/mget.html

基于Redis的短链接设计思路的更多相关文章

  1. 基于Redis的分布式锁设计

    前言 基于Redis的分布式锁实现,原理很简单嘛:检测一下Key是否存在,不存在则Set Key,加锁成功,存在则加锁失败.对吗?这么简单吗? 如果你真这么想,那么你真的需要好好听我讲一下了.接下来, ...

  2. 基于Redis&MySQL接口幂等性设计

    基于Redis&MySQL接口幂等性设计 欲把相思说似谁,浅情人不知. 1.幂等 幂等性即多次调用接口或方法不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致. 2.幂等使用场景 前 ...

  3. 基于redis实现的点赞功能设计思路详解

    点赞其实是一个很有意思的功能.基本的设计思路有大致两种, 一种自然是用mysql等 数据库直接落地存储, 另外一种就是利用点赞的业务特征来扔到redis(或memcache)中, 然后离线刷回mysq ...

  4. openresty && hashids&& redis 生成短链接

    1. 原理     a. 从redis 获取需要表示的短链接的id( redis incr)     b. hashids 编码 id     c. openresty  conteent_by_lu ...

  5. 基于Shiro的登录功能 设计思路

    认证流程 Shiro的认证流程可以看作是个“有窗户黑盒”, 整个流程都有框架控制,对外的入口只有subject.login(token);,这代表“黑盒” 流程中的每一个组件,都可以使用Spring ...

  6. 短链接及关键字过滤ac自动机设计思路

    =============:短链接设计思路:核心:将长字符转为短字符串并建立映射关系,存储redis中.1.使用crc32转换为Long 2.hashids将long encode为最短字符串.作为短 ...

  7. 从零到一手写基于Redis的分布式锁框架

    1.分布式锁缘由 学习编程初期,我们做的诸如教务系统.成绩管理系统大多是单机架构,单机架构在处理并发的问题上一般是依赖于JDK内置的并发编程类库,如synchronize关键字.Lock类等.随着业务 ...

  8. Redis入门指南(第2版) Redis设计思路学习与总结

    https://www.qcloud.com/community/article/222 宋增宽,腾讯工程师,16年毕业加入腾讯,从事海量服务后台设计与研发工作,现在负责QQ群后台等项目,喜欢研究技术 ...

  9. Redis设计思路学习与总结

    版权声明:本文由宋增宽原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/222 来源:腾云阁 https://www.qclo ...

随机推荐

  1. Openwrt flash 空间不足的临时解决方法

    最近有网友在安装软件的时候发现flash空间不够用了: 一个临时的解决方案是在RAM里面使用这个程序.因为 1.路由器改机后的RAM有64MB,flash一般有16MB,RAM空间比较大./tmp是挂 ...

  2. 20145215《Java程序设计》第2周学习总结

    20145215<Java程序设计>第二周学习总结 教材学习内容总结 Java语言中的很多基本语法都和C语言类似,在这里我总结一下Java中的基本语法: 标识符: 标识符是程序中自定义的一 ...

  3. 你需要管理员权限才能删除文件夹及服务器C盘不及批处理

    Windows 7系统,管理员权限设置方法 一.选择文件夹或文件所有者 我们用鼠标右键点击要操作的文件或文件夹 - 属性: 在出现的文件夹属性窗口,我们用鼠标左键点击:安全: 我们用鼠标左键点击:高级 ...

  4. [USACO2005][POJ2454]Jersey Politics(随机化)

    题目:http://poj.org/problem?id=2454 题意:给你3*k(k<=60)个数,你要将它们分成3个长度为k的序列,使得其中至少有两个序列的和大于k*500 分析:以为有高 ...

  5. [C#基础]说说委托+=和-=的那些事

    写在前面 为什么会突然想说说委托?原因吗,起于一个同事的想法,昨天下班的路上一直在想这个问题,如果给委托注册多个方法,会不会都执行呢?为了一探究性,就弄了个demo研究下. += 大家都知道委托都继承 ...

  6. 重构笔记---MEF框架(上)

    概述 这篇文章的目的是简要分析对比MAF和MEF,并详细举出MEF设计中的细节和扩展上的细节,达到让读者能实际操作的目的.其中,MAF的设计会附上我的代码,其实就是官方的代码我自己手动联系了一遍,但还 ...

  7. C#配置文件管理

    最近在做项目的过程中用到配置文件,本文简要说明本人在项目过程中是如何使用配置文件的,目的是加深自己对配置文件管理的理解,以便在下次使用时能做到轻松自如. 配置文件,顾名思义,是用户在使用系统或者软件时 ...

  8. AJAX练习(一):制作可以自动校验的表单(从原理上分析ajax的作用)

    继上文(AJAX(一)AJAX的简介和基础)作为联系. 传统网页在注册时检测用户名是否被占用,传统的校验显然缓慢笨拙. 当ajax出现后,这种体验有了很大的改观,因为在用户填写表单时,签名的表单项已经 ...

  9. The first gui program by Qt

    #include<QApplication> #include<QPushButton> int main(int argc, char **argv) {     QAppl ...

  10. hdu4547 lca tarjan

    比较直接. #include<map> #include<queue> #include<stack> #include<cmath> #include ...