news 2026/4/18 9:51:41

百亿级短链接系统设计:如何用 Redis + MurmurHash 实现高性能的“短网址生成器”?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
百亿级短链接系统设计:如何用 Redis + MurmurHash 实现高性能的“短网址生成器”?

🔗 前言:面试官最爱问的“简单题”

“请设计一个短链接系统,像t.cn/AbCdEf这种。”
这道题在字节、阿里、腾讯的面试中出现的概率高达 80%。

很多初学者会不假思索地回答:“用 Redis 的INCR自增 ID,然后转成 62 进制不就行了?”
错!大错特错!

  1. 安全隐患:自增 ID 是连续的,黑客写个脚本t.cn/1,t.cn/2… 就能遍历你的所有数据,窃取商业机密。
  2. 性能瓶颈:严重依赖 Redis 单点计数器,难以水平扩展。

今天,我们来聊聊大厂主流的**“摘要算法生成法”**,利用MurmurHash + Base62,打造一个安全、无碰撞、可扩展的百亿级短链接系统。


🧠 核心原理:为什么是 MurmurHash?

要将一个长长的 URL 压缩成短字符串,本质上是一个Hash(摘要)过程。

1. 为什么不用 MD5?

MD5 生成的结果是 128 位(32 个字符),太长了!如果我们截取前 6 位,哈希冲突(Collision)的概率会爆炸式增长。

2. MurmurHash 的优势

Google 出品的MurmurHash算法,是目前非加密型 Hash 算法中的王者。

  • 速度快:比 MD5 快几十倍。
  • 雪崩效应好:输入微小的变化,输出巨大的差异。
  • 32 位输出:MurmurHash32 返回的是一个整数,非常适合后续处理。
3. Base62 编码 (压缩的核心)

我们需要把 MurmurHash 算出的整数(比如394820123)转换成更短的字符串。
使用Base62(a-z, A-Z, 0-9 共 62 个字符):

  • 626≈56862^6 \approx 568626568亿
  • 627≈3.562^7 \approx 3.56273.5万亿

结论:只需 6 到 7 位字符,就足够容纳全世界的网页!


⚔️ 核心难点:如何解决“哈希冲突”?

这是这道题的致命考点
虽然 MurmurHash 优秀,但在百亿量级下,冲突是必然的(抽屉原理)。即:
Hash(URL_A) == Hash(URL_B)

工业级解决方案:加盐双重探测

  1. 计算h = MurmurHash(LongURL)
  2. h转为 Base62 字符串,即ShortURL
  3. 查库校验
    • 去 Redis/DB 查这个ShortURL是否已存在。
    • 情况 A (不存在):完美,直接存入。
    • 情况 B (存在,且长链接一致):幂等,直接返回原短链。
    • 情况 C (存在,但长链接不一致)冲突爆发!
  4. 解决冲突
    • 给 LongURL 后面加一个特殊的“盐”(比如DUPLICATE)。
    • 重新执行第 1 步:Hash(LongURL + "DUPLICATE")
    • 直到找到一个不冲突的位置。

🏗️ 架构设计:读写分离与多级缓存

在海量数据下,数据库存不下,Redis 存太贵。我们需要合理的架构。

架构流程图:

访问短链_读链路
生成短链_写链路
1. 提交长链
2. MurmurHash计算
3. 布隆过滤器查重
未命中
命中
加盐重算
1. GET请求
2. 查本地缓存
3. 查分布式缓存
4. 查数据库
5. 回填缓存
6. 302 跳转
重定向服务
用户访问短链
JVM 缓存
Redis Cluster
读取 MySQL
短链生成服务
API 网关
Base62 编码
Bloom Filter
写入 MySQL 分片库
触发冲突解决策略
用户生成请求

关键设计点:

  1. 布隆过滤器 (Bloom Filter):在写入 DB 前,先用布隆过滤器判断短链是否存在。这能拦截 99% 的数据库查询,极大提升写入性能。
  2. 301 vs 302
    • 301 (永久重定向):浏览器会缓存,减轻服务器压力,但无法统计点击量
    • 302 (临时重定向):每次都请求服务器,适合做数据分析(大家一般都选这个)。

🛠️ 代码实战:Java 实现核心逻辑

引入 Google Guava 库来使用 MurmurHash。

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.1-jre</version></dependency>

核心工具类:

importcom.google.common.hash.Hashing;importjava.nio.charset.StandardCharsets;publicclassShortLinkGenerator{// Base62 字符集privatestaticfinalStringBASE62="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";/** * 将 10 进制转 62 进制 */publicstaticStringtoBase62(longnum){StringBuildersb=newStringBuilder();while(num>0){inti=(int)(num%62);sb.append(BASE62.charAt(i));num/=62;}returnsb.reverse().toString();}/** * 生成短链接 */publicStringgenerate(StringlongUrl){// 1. 使用 MurmurHash32 生成 32 位整数// 注意:需处理负数,转为 32 位无符号长整型longhash32=Hashing.murmur3_32_fixed().hashString(longUrl,StandardCharsets.UTF_8).padToLong();// 2. 转 Base62StringshortCode=toBase62(hash32);// 3. 解决冲突逻辑 (模拟)while(isConflict(shortCode,longUrl)){// 加盐重算longUrl+="[SALT]";hash32=Hashing.murmur3_32_fixed().hashString(longUrl,StandardCharsets.UTF_8).padToLong();shortCode=toBase62(hash32);}returnshortCode;}// 模拟数据库查询privatebooleanisConflict(StringshortCode,StringlongUrl){// 实际逻辑:// String existUrl = redis.get(shortCode);// return existUrl != null && !existUrl.equals(longUrl);returnfalse;}}

📊 百亿级优化:分库分表

当数据量达到 100 亿时,单表肯定存不下。
如何分片?

  • 方案:直接用ShortURL做分片键 (Sharding Key)。
  • 逻辑Hash(ShortURL) % 1024,将数据分散到 1024 张表中。
  • 优势:读取时,直接根据短链算出在哪张表,不需要遍历所有库。

📝 总结

设计一个短链接系统,不仅仅是写代码,更是对算法选择、冲突处理、存储架构的综合考量。

  • 拒绝自增 ID:为了安全。
  • 拥抱 MurmurHash:为了速度和随机性。
  • 布隆过滤器:为了极致的写入性能。

掌握了这套方案,面试官问你 TinyURL 设计时,你就可以自信地“降维打击”了。


博主留言:
想获取包含布隆过滤器分库分表配置的完整 Spring Boot 工程源码吗?
在评论区回复“短链”,我发给你一份《百亿级短链系统企业级落地代码》,直接 CV 就能用!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 9:19:59

Simulink双馈风机稳态模型:从理论到实践

simulink 双馈风机稳态模型 包含最大功率跟踪控制&#xff0c;MPPT&#xff0c;参数可调 &#xff08;1&#xff09;转子侧变换器采用基于定子电压定向的矢量控制策略&#xff0c;可以有功无功解耦&#xff0c;具备MPPT能力&#xff0c;采用功率外环电流内环双闭环控制结构&…

作者头像 李华
网站建设 2026/4/18 2:12:53

基于泰坦尼克号数据集的随机森林算法实战

数据预处理 ​ 选取 Pclass &#xff08;船舱等级&#xff09;、 Sex &#xff08;性别&#xff09;、 Age &#xff08;年龄&#xff09;作为特征&#xff0c; Survived &#xff08;是否存活&#xff09;作为标签。 ​用均值填充年龄空值&#xff0c;避免缺失值影响模型训练&…

作者头像 李华
网站建设 2026/4/18 7:38:30

30、Nagios配置与使用全攻略

Nagios配置与使用全攻略 1. Nagios配置基础 Nagios的所有配置都通过“Configuration”选项卡完成。GroundWork将自身配置信息存储在MySQL数据库中。当你在界面上进行更改时,这些更改首先会反映在数据库里。只有当你提交更改后,GroundWork才会将配置转换为单独的Nagios配置文…

作者头像 李华
网站建设 2026/4/17 23:23:50

亿赛通脚本远程调试配置技巧

要进行远程调试&#xff0c;主要是对 Tomcat 和 Java进程 进行调试。以下是针对该系统的远程调试配置方法&#xff1a; 一、Tomcat远程调试配置 1. 修改Tomcat启动脚本 找到Tomcat的启动脚本&#xff08;通常在/esafenet/tomcat/bin/catalina.sh或startup.sh&#xff09;&#…

作者头像 李华
网站建设 2026/4/18 9:42:59

图片转文字技术(一)从光学识别到智能理解的演进之路

引言 在数字化浪潮中&#xff0c;图片转文字技术已悄然渗透到我们日常生活的方方面面。从手机相册中提取证件信息&#xff0c;到扫描纸质文档生成可编辑文本&#xff1b;从自动驾驶汽车识别路牌&#xff0c;到视障人士通过屏幕阅读器获取图像内容——这项技术的应用场景正在不断…

作者头像 李华
网站建设 2026/4/18 5:17:16

【Python与生活】Python实战 | 全网最全QS世界大学排名分析

一、前言 QS世界大学排名是全球最具影响力的大学排名之一&#xff0c;无论是留学选校、学术研究还是高校竞争力分析&#xff0c;都有重要参考价值。本文将手把手教你用Python完成QS排名的数据爬取、清洗、分析与可视化&#xff0c;从0到1实现完整的数据分析流程&#xff0c;即使…

作者头像 李华