当前位置: 首页 > news >正文

[短链接/内推码]生成系统设计

背景和目标

长URL转换成短URL

  1. 用户输入长url获取短url

  2. 用户点击短url可以跳转到长url

需求分析

  1. 要完成上面2个功能

    1. 需要实现短链接生成器

    2. 长链接转换成短链接(持久化存储)

  2. 存储容量

    1. 每月生成URL 5亿条,端URL有效期两年 ⇒ 2*12*5亿 = 120亿

  3. 存储空间

    1. 每条端URL数据库记录大约1KB ⇒ 120亿 * 1KB = 12TB

  4. 吞吐量QPS

    1. 每条短URL,每天平均读取次数100次,那么总的访问量 = 5亿 * 100 = 500亿

    2. 每秒的平均访问量 = QPS = 500亿 / (30 * 24 * 60 * 60) ≈ 20000

    3. 一般高峰期,访问量是平均访问量的2倍 ⇒ 系统架构应该支撑的QPS≈4W

  5. 网络带宽

    1. 短URL的重定向响应包含:长URL地址,约500B

    2. HTTP响应头其他内容大约500B

  6. 耗时:请求响应时间

    1. P80 < 5ms

    2. P99 < 20ms

概要设计

短URL生成器设计:长URL,通过某种函数,计算得到一个6个字符串的端URL

1.方案对比

实现细节

优缺点

方案1

1、长URL利用MD5/sha1(哈希)计算

2、执行base64编码,截取前6位

存在哈希冲突

方案2

1、自增自然数

2、base64编码

优点:唯一,无冲突

缺点:不安全,有规律可循

方案3

预生成短URL

1、预先生成没有冲突的短URL

2、外部请求时,直接从短URL池中获取一个

优点:唯一,无冲突,安全

最终方案:方案3

2.预生成短URL

  1. 预生成端URL算法:采用随机数来实现,转base62,生成6位的字符串作为短URL

  2. 避免短URL冲突

    1. bloom过滤器

  3. 短URL存储

步骤

  1. 先把已经生成的HDFS存放的短URL,全部加载到Bloom过滤器中

  2. 预生成器服务,循环生成短URL

    1. 判断Bloom过滤器中是否存在短URL

      1. 若不存在,说明一定不存在,就更新写Bloom过滤器&&插入HDFS

      2. 若存在,说明可能存在or可能不存在,(认为重复了)直接跳过

3.输入长URL返回短URL

  1. 向HDFS申请一批短URL段

    1. 短链接服务访问HDFS文件的流程:写打开偏移量文件 -> 读偏移量 -> 读打开短 URL 文件 -> 从偏移量开始读取 60K 数据 -> 关闭短 URL 文件 -> 修改偏移量文件 -> 关闭偏移量文件

    2. 分析:系统除了需要一个在 HDFS 记录预生成短 URL 的文件外,还需要一个记录偏移量的文件,记录偏移量的文件也存储在 HDFS 中

    3. 每次读写偏移量文件时,都采用读写锁控制,保证:第一个预加载短 URL 服务器写打开偏移量文件以后,其他预加载短 URL 服务器无法再写打开该文件,也就无法完成读 60K 短 URL 数据及修改偏移量的操作,这样就能保证这两个操作是并发安全的

  2. 减少GC的压力

    1. 短链接分发服务需要保存申请的1w个待分发的短URL,采用的数据结构最好是“环形队列”,消除频繁的内存释放和分配

  3. 减少请求抖动

    1. 问题场景:当size=0时,需要同步请求HDFS,申请size个短URL

    2. 解决方案:环形队列保存定长的buffer,当使用量减少到20%时,开启协程异步去HDFS重新获取(保证环形队里的size不会被消耗殆尽,最少保持20%的buffer)

相关文章:

  • 为什么女性应该考虑从事网络安全事业?
  • python k-means聚类算法 物流分配预测实战(超详细,附源码)
  • 源码硬讲HashMap结构及数据结构转换过程(图+文)
  • 优化程序性能
  • 【Java】【集合】集合框架Collection
  • 这些年,我与Google不得不说的那些事儿
  • Opencv——图像模板匹配
  • 【秋招面经】之神策数据
  • Spring 有几种事务隔离级别?
  • 若依(RuoYi )权限管理设计
  • 【024】 快速上手mongoose web服务器
  • DevOps自动化测试的原则和实践
  • `SpringBoot`+`axios`结合发送`ajax`请求
  • 电子元器件产业发展遇新机,SRM供应商协同管理系统实现与供应商的敏捷协同
  • C#基础入门教程-基本语法
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 《Java编程思想》读书笔记-对象导论
  • Android Studio:GIT提交项目到远程仓库
  • CSS居中完全指南——构建CSS居中决策树
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • Javascript弹出层-初探
  • JDK 6和JDK 7中的substring()方法
  • opencv python Meanshift 和 Camshift
  • Phpstorm怎样批量删除空行?
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 对象管理器(defineProperty)学习笔记
  • 分享几个不错的工具
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • 第二十章:异步和文件I/O.(二十三)
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • $NOIp2018$劝退记
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (C语言)二分查找 超详细
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (一)基于IDEA的JAVA基础10
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • .libPaths()设置包加载目录
  • .net 7 上传文件踩坑
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .net core 6 redis操作类
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .Net 代码性能 - (1)
  • .NET文档生成工具ADB使用图文教程
  • /etc/sudoers (root权限管理)