范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

面试官如何设计一个高并发的短链接系统?

  1 Scenario 场景
  根据一个 long url 生成一个short url。
  如 http://www.javadaily.cn => http://bit.ly/1ULoQB6
  根据 short url 还原 long url,并跳转:
  需和面试官确认的问题:
  long url和short url必须一一对应吗?
  Short url长时间没人用,需要释放吗?  1.1 QPS 分析问日活,如微博100M  推算产生一条 tiny url 的 qps  假设每个用户平均每天 0.1(发10 条,有一条有链接) 条带 URL 的微博  平均写 QPS = 100M * 0.1 / 86400 = 100  峰值写 qps = 100 * 2 = 200  推算点击一条tiny url的 qps  假设每个用户平均点 1 个tiny url  平均写 QPS = 100M * 1 / 86400 = 1k  峰值读 qps = 1k * 2 = 2k  deduce 每天产生的新 URL 所占存储  100M * 0.1 = 10M 条  每条 URL 长度平均按 100 算,共 1G  1T 硬盘能用 3 年
  由2、3 分析可知,并不需要分布式或者 sharding,支持 2k QPS,一台 SSD MySQL 即可。  2 Service 服务 - 逻辑块聚类与接口设计
  该系统其实很简单,只需要有一个 service即可:URL Service。由于 tiny url只有一个 UrlService:  本身其实就是个小的独立应用  也无需关心其他任何业务功能  方法设计:
  UrlService.encode(long_url):编码方法
  UrlService.decode(long_url):解码方法
  访问端口设计,当前有如下两种常用主流风格:  GET / REST 风格
  Return a http redirect resonse  POST /data/shorten(不太推荐,不符合 REST 设计风格,但也有人在用)
  Return a short url
  那么,你们公司的短链系统是选择哪种服务设计呢?  3 Storage 数据存取(最能体现实践经验)select 选存储结构  scheme 细化数据表  3.1 SQL V.S NoSQL
  需要事务吗?No,nosql+1
  需要丰富的 sql query 吗?no,nosql+1
  想偷懒吗?tiny url需要写的代码不复杂,nosql+1
  qps高吗?2k,不高。sql+1
  scalability 要求多高?存储和 qps 都不高,单机都能搞定。sql+1  - sql 需要自己写代码来 scale - nosql,这些都帮你做了
  是否需要 sequential ID?取决于你的算法  sql 提供 auto_increment 的 sequencetial ID,即 1,2,3  nosql 的 ID 不是 sequential  3.2 算法
  long ur 转成一个 6 位的 short url。给出一个长网址,返回一个短网址。
  实现两个方法:  longToShort(url)  把一个长网址转换成一个以http://tiny.url/ 开头的短网址 shortToLong(url)  把一个短网址转换成一个长网址
  标准:  短网址的key的长度应为6 (不算域名和反斜杠)。可用字符只有  [a-zA-Z0-9] . 比如: abcD9E  任意两个长的url不会对应成同一个短url,反之亦然。
  用两个哈希表:  一个是短网址映射到长网址  一个是长网址映射到短网址
  短网址是固定的格式: "http://tiny.url/" + 6个字符, 字符可任意。
  为避免重复, 我们可以按照字典序依次使用, 或者在随机生成的基础上用一个集合来记录是否使用过。  使用哈希函数(不可行)
  如取 long url的 MD5 的最后 6 位:  快  难以设计一个无哈希冲突的哈希算法  随机生成 shortURL+DB去重
  随机取一个 6 位的 shortURL,若没使用过,就绑定到改 long url。  public String long2Short(String url) {   while(true) {     String shortURL = randomShortURL();     if (!databse.filter(shortURL=shortURL).exists()) {       database.create(shortURL=shortURL, longURL=url);       return shortURL;     }   }    }  public class TinyUrl {          public TinyUrl() {         long2Short = new HashMap();         short2Long = new HashMap();     }      /**      * @param url a long url      * @return a short url starts with http://tiny.url/      */     public String longToShort(String url) {         if (long2Short.containsKey(url)) {             return long2Short.get(url);         }          while (true) {             String shortURL = generateShortURL();             if (!short2Long.containsKey(shortURL)) {                 short2Long.put(shortURL, url);                 long2Short.put(url, shortURL);                 return shortURL;             }         }     }      /**      * @param url a short url starts with http://tiny.url/      * @return a long url      */     public String shortToLong(String url) {         if (!short2Long.containsKey(url)) {             return null;         }          return short2Long.get(url);     }      private String generateShortURL() {         String allowedChars = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";          Random rand = new Random();         String shortURL = "http://tiny.url/";         for (int i = 0; i < 6; i++) {             int index = rand.nextInt(62);             shortURL += allowedChars.charAt(index);         }          return shortURL;     } }
  优点:实现简单
  缺点:生成短链接的速度,随着短链接越多而越慢
  关系型数据库表:只需Short key和 long url两列,并分别建立索引
  也可使用 nosql,但需要建立两张表:  根据 long 查询 short key=longurl 列=shorturl value=null or timestamp  根据 short 查询 long key=shorturl 列=longurl value=null or timestamp  进制转换 Base32(微博实现方案)
  Base62:  将 6 位 short url 看做一个 62 进制数(0-9,a-z,A-Z)  每个 short url 对应到一个整数  该整数对应 DB 表的主键
  6 位可表示的不同 URL:  5 位 = 62^5=0.9B= 9亿  6 位 = 62^6=57B= 570亿  7 位 = 62^7=3.5T= 35000亿
  优点:效率高
  缺点:强依赖于全局的自增 id  public class TinyUrl {     public static int GLOBAL_ID = 0;     private HashMap id2url = new HashMap();     private HashMap url2id = new HashMap();      private String getShortKey(String url) {         return url.substring("http://tiny.url/".length());     }      private int toBase62(char c) {         if (c >= "0" && c <= "9") {             return c - "0";         }         if (c >= "a" && c <= "z") {             return c - "a" + 10;         }         return c - "A" + 36;     }      private int shortKeytoID(String short_key) {         int id = 0;         for (int i = 0; i < short_key.length(); ++i) {             id = id * 62 + toBase62(short_key.charAt(i));         }         return id;     }      private String idToShortKey(int id) {         String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";         String short_url = "";         while (id > 0) {             short_url = chars.charAt(id % 62) + short_url;             id = id / 62;         }         while (short_url.length() < 6) {             short_url = "0" + short_url;         }         return short_url;     }      /**      * @param url a long url      * @return a short url starts with http://tiny.url/      */     public String longToShort(String url) {         if (url2id.containsKey(url)) {             return "http://tiny.url/" + idToShortKey(url2id.get(url));         }         GLOBAL_ID++;         url2id.put(url, GLOBAL_ID);         id2url.put(GLOBAL_ID, url);         return "http://tiny.url/" + idToShortKey(GLOBAL_ID);     }      /**      * @param url a short url starts with http://tiny.url/      * @return a long url      */     public String shortToLong(String url) {         String short_key = getShortKey(url);         int id = shortKeytoID(short_key);         return id2url.get(id);     } }
  因为要用到自增 id,所以只能用关系型 DB 表:
  id主键、long url(索引)  4 Scale
  如何提高响应速度,和直接打开原链接一样的效率。
  明确,这是个读多写少业务。  4.1 缓存提速(Cache Aside)
  缓存需存储两类数据:  long2short(生成新 short url 需要)  short2long(查询 short url 时需要)
  4.2 CDN
  利用地理位置信息提速。
  优化服务器访问速度:  不同地区,使用通不同 web 服务器  通过 dns 解析不同地区用户到不同服务器
  优化数据访问速度  使用中心化的 MySQL+分布式的 Redis  一个 MySQL 配多个 Redis,Redis 跨地区分布
  4.3 何时需要多台 DB 服务器
  cache 资源不够或命中率低
  写操作过多
  越来越多请求无法通过 cache 满足
  多台DB服务器可以优化什么?  解决存不下:存储  解决忙不过:qps
  那么 tiny url 的主要问题是啥?存储是没问题的,重点是 qps。那么,如何 sharding 呢?
  垂直拆分:将多张表分别分配给多台机器。对此不适用,只有两列,无法再拆分。
  横向拆分:
  若id、shortURL 做分片键:  long2short 查询时,只能广播给 N 台 db 都去查询  为何要查 long2short?避免重复创建呀  若不需要避免重复创建,则这样可行
  用 long url 做分片键:
  short2long 查询时,只能广播给 N 台 DB 查询。  4.3.1 分片键选择若一个 long 可对应多个 short使用 cache 缓存所有 long2short  在为一个 long url 创建 short url 时,若 cache miss,则创建新 short  若一个 long 只能对应一个 short若使用随机生成算法  两张表,一张存储 long2short,一张存储short2long  每个映射关系存两份,则能同时支持 long2short short2long 查询  若使用 base62 进制转换法  有个严重问题,多台机器之间如何维护一个全局自增的 id?  一般关系型DB只支持在一台机器上实现这台机器上全局自增的 id  4.4 全局自增 id4.4.1 专用一台 DB 做自增服务
  该 DB不存储真实数据,也不负责其他查询。
  为避免单点故障,可能需要多台 DB。  4.4.2 使用 zk
  但使用全局自增 id 不是解决 tiny url最佳方案。Generating a Distributed Sequence Number  4.5 基于 base62 的分片策略
  Hash(long_url)%62作为分片键
  并将 hash(long_url)%62直接放到 short url
  若原来的 short key 是 AB1234,则现在的 short key 是  hash(long_url) % 62 + AB1234  若 hash(long_url)%62=0,那就是0AB1234
  这样,就能同时通过 short、long 得到分片键。
  缺点:DB 的机器数目不能超过 62。
  所以,最后最佳架构:
  4.6 还能优化吗?
  web server 和 database 之间的通信。
  中心化的服务器集群和跨地域的 web server 之间通信较慢:如中国的 Server 需访问美国的 DB。
  为何不让中国的 Server 访问中国的 DB 呢?
  若数据重复写到中国 DB,如何解决一致性问题?很难解决!
  思考用户的习惯:  中国用户访问时,会被 DNS 分配中国的服务器  中国用户访问的网站一般都是中国的网站  所以可按网站的地域信息来 sharding  如何获得网站的地域信息?只需将用户常访问的网站汇总在一张表。  中国用户访问美国网站咋办?  就中国 server 访问美国 db,也不会慢太多  中访中是用户主流,优化系统就是针对主要需求
  于是,得到最终架构:
  还可以维护一份域名白名单,访问对应地域的 DB。  5 用户自定义短链接
  实现一个顾客短网址,使得顾客能创立他们自己的短网址。即你需要在前文基础上再实现一个  createCustom 。
  需实现三个方法:  long2Short(url)  把一个长网址转换成一个以http://tiny.url/ 开头的短网址 short2Long(url)  把一个短网址转换成一个长网址 createCustom(url, key)  设定一个长网址的短网址为 http://tiny.url/  + key
  注意:  long2Short  生成的短网址的key的长度应该等于6 (不算域名和反斜杠)。可以使用的字符只有 [a-zA-Z0-9] 。如: abcD9E  任意两个长的url不会对应成同一个短url,反之亦然  如果  createCustom  不能完成用户期望的设定, 那么应该返回 "error" , 反之如果成功将长网址与短网址对应,应该返回这个短网址 5.1 基于 Base62
  在URLTable里,直接新增一列custom_url记录对应的custom url是否可行?
  不可行!对于大部分数据,该列其实都为空,就会浪费存储空间。
  新增一个表,存储自定义 URL:CustomURLTable。
  创建自定义短链接:在 CustomURLTable 中查询和插入
  根据长链接创建普通短链接:  先查询CustomURLTable是否存在  再在URLTable查询和插入
  同前文一样,用两个哈希表处理长网址和短网址之间的相互映射关系。需额外处理的是用户设定的网址与已有冲突时,需返回 "error"。注意:若用户设定的和已有恰好相同,则同样应该返回短网址。  public class TinyUrl2 {     private HashMap s2l = new HashMap();     private HashMap l2s = new HashMap();     private int cnt = 0;     private final StringBuffer tinyUrl = new StringBuffer("http://tiny.url/");     private final String charset = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM";          private String newShortUrl() {         StringBuffer res = new StringBuffer();         for (int i = 0, j = cnt; i < 6; i++, j /= 62)             res.append(charset.charAt(j % 62));         cnt++;         return tinyUrl + res.toString();     }          /*      * @param long_url: a long url      * @param key: a short key      * @return: a short url starts with http://tiny.url/      */     public String createCustom(String long_url, String key) {         String short_url = tinyUrl + key;         if (l2s.containsKey(long_url)) {             if (l2s.get(long_url).equals(short_url))                 return short_url;             else                 return "error";         }         if (s2l.containsKey(short_url))             return "error";         l2s.put(long_url, short_url);          s2l.put(short_url, long_url);         return short_url;     }      /*      * @param long_url: a long url      * @return: a short url starts with http://tiny.url/      */     public String longToShort(String long_url) {         if (l2s.containsKey(long_url))             return l2s.get(long_url);         String short_url = newShortUrl();          l2s.put(long_url, short_url);          s2l.put(short_url, long_url);         return short_url;      }      /*      * @param short_url: a short url starts with http://tiny.url/      * @return: a long url      */     public String shortToLong(String short_url) {         if (s2l.containsKey(short_url))             return s2l.get(short_url);         return "error";     } } 5.2 基于随机生成算法
  无需做任何改动,直接把custom url当short url创建即可!

你看狂飙了吗?怎么独安欣白了头?狂飙早已完结,我才追到30集,看到这里,我最不解的就是为啥大家都是黑头发,只有安欣一个人白了头?一部扫黑电视剧,一瞬间火遍大江南北,除了演员的演技到位之外,剧情更是饱满充实,跌宕起中国能建安徽电建二公司召开2022年度党支部书记述职会暨联学联建融通融合六个一主题行动总结大会中国经济周刊经济网讯1月30日,中国能建安徽电建二公司召开2022年度党支部书记述职会暨联学联建融通融合六个一主题行动总结大会。公司党委书记董事长陈建明出席会议并作题为强化党建引领1座车站4座大桥获国家级奖项,哪个离你家最近?近日中国施工企业管理协会发布了关于公布20222023年度第一批国家优质工程奖入选工程名单的通知长三角铁路1座车站4座大桥获得国家优质工程奖盐通高铁海安特大桥海安特大桥位于江苏省盐河南省2023年普通高校招生体育类专业统一考试(含专升本对口生)有关事项我省2023年普通高校招生体育类专业统一考试(以下简称体育省统考)将于3月下旬开始进行,现将考试有关事项告知如下一考试时间2023年3月20日至4月7日,分批次进行。考生按网上约定ChatGPT会取代人类工作岗位吗?想聊天,但小心被骗!ChatGPT,最擅长的不止聊天最近应用软件ChatGPT一夜爆红它很擅长聊天无论问题多么天马行空给出的答案看上去都有理有据不仅能说会道还明辨是非写打油诗也还可以有人拿它编大纲有人知味甘肃不一样的陇上罐罐茶知味甘肃不一样的陇上罐罐茶罐罐茶茯茶文李子伟在大西北的农村,自古就有一种独特的品茗风俗习惯罐罐茶,特别是在甘肃天水定西陇南一带,这种饮茶文化非常流行。罐罐茶不像是西湖龙井铁观音一样狂飙里你觉得高启强还是输了还是赢了?电视剧狂飙已经全剧终有一段时间了,但是热度一直不减!大家讨论的点也逐渐从扫黑除恶转移到了谁才是最后的赢家?其中,要说赢家,导演和主创团队肯定是要通过电视作品表达国家扫黑除恶惩恶扬善大战再起据悉俄1800辆坦克400架战机2700门火炮已云集乌东据乌克兰国防部官员估计,目前俄军已在乌东调集超过1800辆坦克400架战机3950辆装甲车810套火箭炮系统300架直升机以及2700门火炮。种种迹象显示,俄军将在10日左右的时间如果不喜欢推荐的内容,有一个简单的解决办法第一步,用手机打开今日头条点击最右下角我的第二步,点击最右上角的设置按钮第三步,打开隐私设置第四步,在隐私中心点击个性化推荐设置第五步,在个性化推荐设置里,根据自己需要,关掉相关设全球纺织品服装贸易回顾消费者支出疲软中国对美出口下降中国棉花网专讯国际棉花咨询委员会(ICAC)的分析报告称,新冠疫情期间全球经济衰退和随后的复苏严重扰乱了全球价值链,导致全球纺织品服装出口额下降52020年出口额为7820亿美元,GTAOL内容更新三倍奖励尽在生死相许GTAOL迎来内容更新,情人节主题服装上线,还有众多福利活动正在进行中,一起来看一下吧未来的前景很可怕。为什么不驾着卡拉斯科百老汇(肌肉车),回到未来主义设计还是乌托邦式和充满希望
被这4种显脏色害惨的中老年人,自己还不知道,今冬赶快扔掉时尚无关年龄的观念深入人心,很多中老年人也开始关注时尚,希望通过穿衣打扮改善形象,穿得优雅洋气一点。而改善穿搭,除了要用时尚单品替换过时老年装外,大家还要关注颜色,别让一些视觉显脏冬季严寒,提醒中老年人准备好过冬5宝,体格强健胃口好人们常说秋收冬藏,在经过秋季丰收后,冬季的气候特点虽对人们不太友好,但也刚好是万物休养的好时节。对于上了年纪的人来说,难免会因体质弱而受寒引起不适,不妨可以通过温和的食补方式来给身世界杯花落谁家揭晓前,一起了解下古代蹴鞠历史周日晚,世界杯决赛将展开角逐,本届卡塔尔世界杯也将落下帷幕。冷空气来袭,夜里看球记得添衣。本场决赛看点多多,姆巴佩与梅西的新老球王之争,法国队能否打破长达62年的卫冕魔咒,阿根廷队翻译三分球对詹姆斯得分记录的影响LeBronJamesisexpectedtosurpassKareemAbdulJabbarastheNBAscareerleaderinpointsscoredinthereg火箭骑士三方交易报价!费尔蒂塔送走122后卫,伊森获首发良机?报价背景火箭目前在西部倒数第一,直奔文班亚马而去,势必明年摆烂成功,而今年他们的任务就是培养新人,格林和史密斯伊森的快速成长才是必须的,老将戈登已不再球队的未来计划之中,费尔蒂塔打兰兹博格305陶汉林1918山东六人得分上双险胜山西北京时间12月16日1935,20222023赛季CBA常规赛第14轮,山东队121118战胜山西队。比赛现场技术统计山东队兰兹博格30分5篮板3助攻高诗岩18分8篮板10助攻5抢8换1!火箭报价特雷杨,豪送5个首轮签北京时间12月16日,NBA常规赛正在如火如荼的进行之中,就在刚刚结束的一场焦点战之中,由主场作战的休斯顿火箭队对阵前来挑战的迈阿密热火队。最终热火在希罗41分6篮板2助攻的助力下湖南湘潭富豪榜大洗牌,步步高老板遗憾出局,周群飞身价腰斩素有湘中灵秀千秋永,天下英雄一郡多美誉的湘潭市位于湖南省中部,地处湘江下游流域,是长江中游城市群的重要组成部分,同时也是长株潭都市圈的核心成员。湘潭历史悠久,自古人杰地灵,是湖湘文生活中有哪些残忍的真相?1一个人就算再努力,如果没有好的结果也是不被认可社会很现实,别人不会管你过程付出了多少,多么的努力,只看结果如果没有收获,所有的努力都是白费。2只有父母才是真心希望自己好父母对子女为何股票遇到三线金叉会涨?揭秘神秘的三线金叉战法有些人说这个世界太奇怪了,奇怪到什么程度呢?很多的一些东西违背常识,人们往往喜欢套路不喜欢深情,譬如在这个世界上,坏人赚钱而好人往往平庸无奇,自古红颜多薄命,你最期待的那个人到最后中概股退市警报解除了?作者丨王俊编辑丨陈磊图源丨视觉中国当地时间12月15日上午,美国公众公司会计监督委员会(PCAOB)发布报告,确认2022年度可以对中国内地和香港会计师事务所完成检查和调查,撤销2