周三下午,产品经理丢过来一个需求:把站内几百万条商品链接全部转成短链,还要保证十年内不重复。你打开编辑器,第一反应可能是"这得多少位字符才够用"。
![]()
答案比想象中克制:7 个字符。按 Base62 编码算,每个字符可取 62 种状态(0-9、a-z、A-Z),7 位一共是 62 的 7 次方,约 3.5 万亿种组合。而十年内需要承载的记录量是 3650 亿条,两者之间还留着一个数量级的余量。
这套方案的骨架其实很朴素,拆开看就三件事:
- 生成:写请求进来,先用分布式 ID 生成器(比如雪花算法)拿到一个唯一递增 ID,再把它转成 Base62 字符串,落库。
- 读取:短链到长链的映射放进 Redis,热点链接几乎不用碰数据库。
- 跳转:返回 301 永久重定向,浏览器自己就能缓存,服务器压力再降一层。
为什么读要单独优化?因为读比写多出 10 倍。短链服务天生是读多写少的形态,一次生成之后会被反复访问,缓存命中率直接决定这套系统扛不扛得住。
编码方式的选择也有讲究。用哈希取模同样能得到短码,但碰撞是绕不开的——一旦撞了就得重试,或者上布隆过滤器兜底。而"唯一递增 ID + Base62 转换"这条路,从源头上就不存在碰撞,省掉了整套重试逻辑。
代价是另一个问题:ID 递增意味着短码可预测,别人能顺着枚举你的链接。缓解办法有两个方向,加盐,或者干脆不连续分配 ID。
自定义短码是另一个容易踩坑的地方。用户指定了一个字符串,恰好和系统生成的撞上,处理原则是"先到先得"——谁先提交谁拥有,不管提交方是系统还是用户。保证这一点靠的是事务锁或乐观锁。
回头看那个需求,7 个字符撑起 3650 亿条链接,靠的不是什么黑科技,是把 ID 生成、编码、缓存、重定向四件事各自做对,再让它们串起来。系统设计里很多"撑得住"的答案,都是这么来的。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.