京东短网址高可用提升最佳实践 | 京东云技术团队
作者:京东零售 郝彦军
什么是短网址?
短网址,是在长度上比较短的网址。简单来说就是帮您把冗长的 URL 地址缩短成 8 个字符以内的短网址。
当我们在腾讯、新浪发微博时,有时发很长的网址连接,但由于微博只限制 140 个字,所以微博就自动把您发的长网址给转换成短网址了。在微博和手机短信提醒等限制字数的地方来使用短网址,的确是一个不错的方案。
短网址通常使用“短域名/短码”的形式,打开短网址网页会直接跳转到长网址页面。例:3.cn/CdEyF2、t.cn/RlB2PdD、dwz.cn/134128 等短网址,分别是由以下短网址服务缩短后的网址 京东短网址:http://s.3.cn/, 新浪短网址:https://sina.lt/ ,百度短网址:http://dwz.cn/。
短网址服务主要包含功能: 生成短网址(长网址缩短)、二维码简化、修改短网址、短网址跳转(访问短网址跳转到长网址)、唤醒 APP、短网址统计 等。
短网址能解决什么问题?
长网址存在的问题:
1、长网址的长度太长,下面的长网址,共记 312 个字符,在微博场景中,限制 140 字符,已无法发布出去。在短信场景中,限制 70 字符,会产生 5 条短信费用,被拆分后还无法访问,严重影响用户体验。http://wjorder-http.jd.com/scan/np?encodePrcode=2hP_lwNr&encodeShcode=2-S83&businessSource=1&scanSkuType=2&ec=1&salerId=167916&discountsUrl=%2F%2Fcoupon.m.jd.com%2Fcoupons%2Fshow.action%3FlinkKey%3DAAROH_xIpeffAs_-naABEFoePLd7eC4GJgwsPUkFtDqklu805DO1cEqFyTHVT7fbD12AHD7DElAKgh0pfvQpX-E5PbgwLQ&unionId=1001465750
2、长网址生成的二维码,极其复杂 ,导致手机扫描识别极其困难,低端手机甚至无法识别,严重影响用户体验。
短网址则完美解决了上述问题:
1、使用短网址服务缩短上面长网址后的短网址(3.cn/1jK-CDAE),仅有 13 个字符,在微博、短信等场景中发送十分容易,而且简洁清晰,用户体验极好。
2、短网址生成的二维码,极其简洁 ,非常容易识别,用户体验良好。
京东短网址的业务场景:
京东短网址http://s.3.cn/,是京东唯一的短网址服务平台,已应用到京东体系的各个业务场景中,日均产生 1 亿条带有 3.cn 的短消息,点击短网址还可直接唤起对应的 APP 和小程序。
如下图 1-2 是来自七鲜、金龙鱼、京东金融、蒙牛、京东等业务的营销消息,下图 3-4 是唤起七鲜小程序、京东 APP、金融 APP 并跳转至落地页的截图。
图 1
图 2
图 3
图 4
京东短网址服务的架构优化:
改造前短网址生成流程图说明:
1、系统首先查询长网址(长链)是否已存在于 redis(jimdb)或 hbase 中,
2、如果长链已存在,则表示该长网址已经生成过,可直接返回查到的短网址,流程结束。
3、如果长链不存在,则使用长网址进行 MD5 随机算法生成一个长串,并分成 3 段,转化成 62 进制短码,拼装成短网址,然后查询短网址(短链)是否存在于 redis 或 hbase 中
4、如果短链不存在,则保存长网址到短网址的映射、以及短网址到长网址的映射,到 redis 或 hbase 中,返回短网址,流程结束。
5、如果短链已存在,说明随机算法生成的短码发生了冲突碰撞,需要循环回到步骤 3,加盐重新生成一个短码,直到生成的短码检测没有冲突后,走到步骤 4 结束。
从原流程图分析原系统优劣势:
优势:采用随机算法,同一长链在同一账号下始终唯一,适用于长网址大量重复生成的情景,可以在步骤 2 快速返回,且随机算法遍历难度相对较高。
劣势:外部操作太多,性能影响较大,每次生成短网址涉及的网络请求次数至少 8 次(2 次查 redis、2 次写 redis、2 次查 hbase、2 次写 hbase)。
且从上面步骤 5 可以看出,系统存在一个碰撞循环,随着短码数据量日益增加,碰撞率也会大大增加,每次碰撞都要额外增加 1 次 redis 与 1 次 hbase 查询,导致性能越来越差。
分析原流程 &历史数据,寻找原流程优化点:
1、 从原流程可以看出,如果继续采用随机算法,很难进行优化,因此,想到了可以采用自增算法,因为自增不存在碰撞,就不需要进行双向检索存储,能够极大的降低外部请求数。
2、 分析历史数据发现,很少存在长网址被大量重复生成的情况,也就是说,可以采用自增算法的单向存储(仅存储短网址到长网址的映射),并不会增加存储量,反而会比随机算法的双向存储(存储短到长的映射,及长到短的映射,即双倍存储)节省存储量。
3、 分析历史数据发现,90%超过 1 个月的短网址都不再有访问量了,同时调研业务也发现,43%用户 1 个月有效期就够了,46%用户 3 个月,10%用户 1 年,极少有用户需要短网址永久有效。
4、 分析历史数据发现,生成的数据量很大,日均 1 亿+,且大多数短网址并不需要永久保存,需要做好清理规划
5、 分析历史数据发现,生成量远大于跳转量,跳转服务流程简单仅做查询,优化空间不大,倒是对生成服务性能要求极高,优化重点在于生成服务。
优化后的短码生成流程说明:
1、 系统直接采用自增算法生成了一个短码,因为自增算法没有了随机碰撞,也就不需要再检索短网址是否存在 redis 或 hbase 中。
2、 直接保存短网址到长网址的映射到 redis 中,因为没有了检索长网址是否存在于 redis 或 hbase,也就不再需要保存长网址到短网址的映射,也就可以把 hbase 的写入改成异步写入,然后直接返回短网址,流程结束。(可以看到系统仅剩下 1 次同步的 redis 操作,流程极大简化,可以预见接口性能将得到极大提升)
自研专利算法介绍
细心的同学可能会有疑问,上面的分布式自增算法是怎么实现的呢?
目前市面上已知方案,1、通过数据库自增(并发 QPS 数有限)2、通过 redis 自增(存在单 key 热点问题,也就是所有的发号请求都会打到同一分片上),两种方案均会增加性能损耗,且存在扩展瓶颈,无法满足京东的海量业务请求。3、雪花算法(长度太长不符合,短网址要求长度一般在 7 个字符)
因此设计了下面的专利自增算法:(性能近乎于内存,损耗可忽略)
下面介绍一下核心的自增算法原理:主要采用缓存发号加内存自增方式,既无碰撞率又性能极高,主要体现在下图的三条彩色通道上面。
1、绿色通道:内存发号,速度极快,每次从缓存取出 10000 个无重复号码,然后在内存中便可连续生成 10000 个短码,因此速度比传统基于数据库及缓存自增发号方式快万倍。
2、蓝色通道:缓存取号,依赖缓存保证分布式发号无碰撞,批量发号,每 1 万次内存绿色通道才走一次蓝色缓存通道取号,因此性能极高
3、红色通道:保障机制,保障生成的号码都在短网址对应长度的号码总容量范围内,仅在初始化及总容量用尽时执行,性能损耗可忽略不计。
长度 &有效期规划:
• 有访问会自动延期 N 天(7 位短码总容量 3 万亿,过期时间 30 天,每天有 1000 亿短码可用,30 天内有 1 次访问就会重置 30 天有效期,也就是说保持“热数据”始终在 redis 中)
• 连续 N 天无访问自动回收(7 位短码,连续 30 天没有访问的情况下,才会过期回收,也就是说“冷数据”无访问 N 天后会自动过期清理回收)
以下统计了最近 6 天的各短码长度的使用分布占比情况,目前使用最多的是 7 位与 8 位短码,占比总和近 90%。其中 43%的用户选择了 30 天有效期,46%的用户选择来了 100 天有效期。
提效成果:
Ø 接口性能极大提升:tp999:从 150+ms ->7ms,解决了业务调用缓慢及超时的痛点
Ø 单机承载量极大提升:单机 QPS:从 497->10184,提升了 20 倍+,无扩容支撑了日生成量:从 1 千万->2 亿+
Ø 按百度短网址费用核算,1 年可节约 2700 万元(证明短网址产生价值很大
Ø redis 缓存 30 天热数据,缓存量 1.2TB
Ø Hbase 存储全量数据,存储量 4TB
Ø 6 月 18 日生成量 4.7 亿、6 月日均 1 亿、峰值 QPS 7.2 万
Ø 6 月 1 日跳转量 1600 万、6 月日均 800 万
Ø 线上仅 8 台 4 核 docker(优化后日常节约了 760 核机器,618 节约 3572 核)
Ø 有访问自动延期,无访问自动过期回收,避免了死码长期占用资源消耗费用,避免短码越积越多导致的数据量太大及性能下降,系统可长期稳定运行
创新性:
Ø 产出技术发明 专利 1 篇,编号:JDZL2019N5022
Ø 技术关键点是分布式 无碰撞 高效 短码生成算法:
Ø 该算法利用 redis 的 incrby 实现分布式号段发放(5 位短码每次发放 1000 个号,当然 6、7 位短码可设置更大步长值 10000 个),利用本机原子 id 自增减少 redis 请求(每 10000 个 id 自增后请求 1 次 redis),因为 id 始终自增所以短码无碰撞概率(id 可以直接转化为 62 进制短码),避免了因短码碰撞带来的循环生成检索的性能开销。利用 redis.set 原子检测 key 不存在时才能设置成功实现分布式加锁,解决多线程并发重置问题,最终实现比传统自增方案快万倍的高性能无碰撞短码自增算法。
Ø 利用容量规划及过期时间机制(5 位短码总容量 9 亿,有效期 10 天,每天有 9 千万可用),实现号段循环重复利用(10 天后第 1 天的号段过期,可以再次使用)(当然如果是 6 位短码、总容量有 550 亿,有效期也可以更长。7 位短码总容量 3 万亿,基本可以不用过期了),保障了系统的长期稳定运行。
影响力:
Ø 宙斯平台-京麦服务市场中上架,有**470+**京东商户应用使用。3.cn/1-jMkHBf
Ø 3.cn 作为京东唯一的短网址服务平台,合作的应用 50+(京东 APP、京东金融、京东云、京东保险、七鲜、京东健康、京东物流等等)、小程序 20+、合作的二级部门 80+
版权声明: 本文为 InfoQ 作者【京东科技开发者】的原创文章。
原文链接:【http://xie.infoq.cn/article/8e3bd72ccceec695cf523b583】。文章转载请联系作者。
评论