京东短网址高可用回收策略分析

京东原文: 京东短网址高可用提升最佳实践 | 京东云技术团队 - 知乎

此篇文章缺少回收策略,故根据其文章流程图梳理出其架构,分析短链回收策略


业务方通过短链服务提供的sdk将长链转换为短链,结构如下

京东短网址高可用回收策略分析_第1张图片

目前疑问:难点就是如何复用之前的号段

京东短网址高可用回收策略分析_第2张图片

京东短网址高可用回收策略分析_第3张图片

先来梳理一下文章中的一些内容,上面截了两张图,从中可以得知:

  1. 如生成的断链有被访问,会根据规则自动续期(热点数据始终在redis中)
  2. 5位短链(这里拿5位的先举例),有效期10天,第10天的时候,第一天未被访问的断链就会过期,按平均来算,最大会过期大约9千万的短链
  3. 5位短链每次发放1000个号,而且这个数量是可以配置的。(业务方拿到的这1000个号其实可以看做是:beginNum=1,endNum=1000)
  4. hbase中有全量数据(因异步写也会失败,这里乐观认为都是成功的)

以上几点是根据文章推断出来的,再补充一个:短链服务记录每天使用的id开始与结束(只要派发给业务方即记录)


得到以上几点信息,我们可以做一个 回收池(拿5位短链举例):

  • 根据过期时间(10天)获取那一天的使用的自增ID的区间,然后去redis扫描
  • 扫描规则可以按照 派发的最大值来操作,如区间(1-1000)在redis中无法查到,则认定这一区间段是可以被复用的,写成记录存表(只存beginNum,endNum)

        例如:5位短链一天9千万数据,假设第一天的短链全都都没使用,按最大派发值来算:90000000/1000=90000,也仅仅会生成9万数据,如需减少扫描区间到100,一 天也只会生产90万数据,对比之前的9千万条数据,性能提升了百倍千倍


改造后流程(拿5位短链举例):

  • 业务方->sdk->短链服务
  • 短链服务:查看回收池是否有数据,有则优先使用回收池数据(因5位短链可能会减少扫描区间,所以单条记录不足1000,可考虑合并返回sdk多个区间段)
  • sdk:获取到N个区间段(可能多个区间段之和都不足1000),按照之前的流程递增使用即可,当本地N个区间段都使用完毕,则再次请求短链服务获取N个区间

可优化的点:

  • 这里的规则是按照 派发的最大值来操作,所以性能会更高,但是复用率会降低(可以提供多种策略:适当减少扫描区间,提升复用率,降低扫描性能)

                举例:5位短链因数量少可以减少扫描区间提高复用率,而6/7位短链非常多,则可以按最大派发值来提升扫描性能

  • 扫描redis的策略,因目前粗略考虑,就直接传区间所有值查(这里可以考虑更优解)

扫描策略优化:

        同样先说痛点(拿5位短链举例):一天最大过期9千万条,对于上述的流程:是拿每天记录的beginNum 和 endNum去拆分区间值去redis中批量扫描,这种效率当然低下,本质上还是让redis帮我们查了9千万数据,即使网络IO可能只有9万次(1000一次条),但是这里有两个问题:

  1. 9万次请求总计返回了9千万数据,占用了很多带宽
  2. 对redis会造成一定压力,每次请求都要去扫描1000个数据,因核心任务线程是单线程,势必对正常请求造成一定程度上的阻塞(如果是6/7位短链那将影响更大)

优化方案:

  • 在记录每天总数的基础上,再记录每次派发给业务方的所有区间段
  • 之前sdk在使用区间段时,每使用一个都会向redis新增对应映射关系

        key(短链)value(长链),改造成:key(短链)value(长链,所处区间段[例如:0-1000])

        现再次基础上改造value,同时向redis中再写一条 区间映射 ,过期时间和当前set的短链映射时间保持一致

        key(0-1000) value(当前时间)

  • 之前有个设定:每次访问短链会自动续期N天

        在此基础上,再将第二步所描述的 区间映射也续期N天,保持一致

  • 定时任务:根据过期策略配置的时间查询所有需要检测的区间段,然后去redis查区间映射,如存在则证明其区间中的短链有被使用,否则反之

优化前后对比(5位短链举例):

        优化前:需要调redis9万次,每次传输1000个key,每次redis响应也最大1000个value,占用大量带宽,拖累redis正常执行

        优化后:需要调redis9万次,每次传输1个key,每次redis响应1个value

到此完毕。

你可能感兴趣的:(java)