1. 首页 > 快讯

vivo 自研鲁班分布式ID服务实践

今天给各位分享vivo 自研鲁班分布式ID服务实践的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

1.1.1 系统分库分表随着系统的持续运行,传统的单库单表在支持更高数量级的规模时,在性能或稳定性方面不再可持续。我们需要对目标逻辑数据表进行合理的物理拆解。点来说,这些相同业务表数据的拆分需要一套完整的ID生成方案,以保证拆分后的物理表中的相同业务ID不冲突,并且能够在后续的合并分析中方便快捷地进行计算。

以公司营销系统的订单为例,目前为不但以分销与零售的目标组织区别来进行分库存储,来实现多租户的数据隔离,并且会以订单的业务属性(订货单、退货单、调拔单等等)来进一步分拆订单数据。创建订单时,根据这些规则构造一个全局唯一的ID,创建订单文档并保存在相应的数据库中;通过订单号查询时,利用ID规则快速将查询路由到对应的数据库表;在BI数据仓库的统计业务中,需要对这些订单数据进行汇总,进行报表分析。

1.1.2 系统多活部署无论是面向全球化各国数据合规诉求还是瞄准容灾高可用的架构设计,我们都会对同一个系统进行多活部署。对于多活部署架构的每个单元化服务,存储的单据(如订单/出入库单/支付单等)都有一个带有部署区域属性的ID结构,形成全局唯一的ID。文件创建并保存在相应单位的数据库中。在前端查询时根据单据编号,通过ID规则,可以将查询快速路由到对应的单位区域。对应多活部署架构的中心化服务,同步各单元文档数据时,文档的ID全局唯一,避免聚合数据时ID冲突。

在公司的系统部署中,公域BPM、待办事项、营销系统均大规模实现多活部署。

1.1.3 链路跟踪技术在微服务架构流行的背景下,此类微服务应用的调用链路比单体应用更长、更复杂,给故障排查带来了挑战。针对该场景的解决方案是,在流量入口处生成一个全局唯一的TraceID,并在微服务之间透传,用于流量着色和关联。随后,通过这个全局唯一的TraceID,可以快速查询并关联整个链路的呼叫关系和状态。快速定位问题根源。

公司的各种监控系统、灰度管理平台、跨进程链接日志等都伴随着这样一个技术组件来提供支撑服务。

1.2分布式ID核心的难点

唯一性: 保持生成的ID全局唯一,任何情况下都不会出现重复值(比如防止时间回滚、时钟周期问题)。高性能: ID有很多需求场景。集中生成组件后,需要高并发处理,大规模并发执行,响应接近0ms。高可用:作为ID的生产源,需要100%可用。当业务系统较多时,很难调整出各方都能接受的停机发布窗口,只能接受无损发布。易接入为了推广使用:作为逻辑简单的分布式ID,必须强调它可以开箱即用,并且易于使用。规律性: 不同业务场景生成的ID有各自的特点,如固定后缀、固定位数等,需要进行配置管理。

1.3分布式ID常见的方案

在常见的系统设计中,主要有如下所示的9种ID生成方法:

1.4分布式ID鲁班的方案

我们的系统跨越多个区域,包括公共、生产制造、营销、供应链、财经。在分布式ID请求下,还有以下特点

在业务场景中,除了常规的Long类型ID外,还需要支持“String类型”、“MixId类型”等多种类型ID的生成(稍后详细介绍)。每种类型还需要支持不同的长度。 ID。 ID组成规则需要覆盖操作类型、区域代理等业务属性的标识;需要集中配置管理。在某些特定业务中,基于安全考虑,需要在末尾添加随机数,以保证ID不被轻易猜到。综合参考了业界优秀的开源组件和通用的解决方案后,都无法满足要求。为了统一管理这样的基础技术组件,我们选择根据公司业务场景开发一套分布式ID服务:鲁班分布式ID服务

二、系统架构

2.1 架构说明

三、 设计要点

3.1支持多种类型的ID规则

目前鲁班分布式ID服务主要提供“Long类型”、“String类型”、“MixId类型”三种类型的ID。相关ID组成规则及说明如下:

3.1.2 Long类型(1)构成规则静态结构由以下三部分数据组成,总共19位个组成部分:

固定部分(4位)

由FixPart+ServerPart组成。

FixPart(4位):4位代码,由区域1位/代理1位/项目1位/应用1位组成。

ServerPart(4位):用于定义生成全局ID的服务器标识位,在部署服务节点时动态分配。动态部分DynPart(13位)

System.currentTimeMillis() - 固定配置时间的TimeMillis(满足100年的使用)。自增部分SelfIncreasePart(2位):用于递增客户端SDK中全局ID的内部部分。由客户端SDK控制,不被服务接入方感知。总共由2人组成。(2)降级机制主要自增部分是服务端获取初始值后由客户端SDK维护的。自增99后,再次访问服务器,获取下一轮新的ID,以减少服务器交互频率,提高性能。服务器获取失败。异常抛出后,需要接入业务方介入处理。

(3)样例说明

3.1.2String类型(1)构成规则静态结构由以下五部分数据组成,总共25~27位个组件:

固定部分操作位op+FixPart(9~11位)

操作位op(2~4位):业务方传入的2~4位业务类型标识字符。

FixPart(7位):接入业务时申请。它由1个区域、2个代理、2个项目和2个应用程序组成。服务器标识部分 ServerPart(1位): 用于定义生成全局ID的服务器标识位。 A~Z代码是在部署服务节点时动态分配的。动态部分DynPart(9位)

System.currentTimeMillis() - 固定配置时间的TimeMillis,然后转换为32位字符串(满足100年使用)。自增部分SelfIncreasePart(3位):用于递增全局ID的客户端SDK内部部分。由客户端SDK控制,不被服务接入方感知。随机部分secureRandomPart(3位):用于全局ID的客户端SDK的随机部分。 SecureRandom随机生成0-9、A-Z字母数字组合的3位安全随机数,服务接入方感知不到。(2)降级机制主要自增部分由客户端SDK内部维护。一般情况下只使用001-999,共999个全局ID。也就是说,每次向服务器发出请求时,客户端中都会自动维护999个唯一的全局ID。特殊情况下,当访问服务器连接出现问题时,可以使用字符自增进行服务器降级处理,产生00A、00B.0A0、0A1、0A2.ZZZ。总共36*36*36 - 1000(999是纯数,000不用)=45656个降级使用的全局ID

(3)样例说明

3.1.3MixId类型(1)构成规则静态结构由以下三部分数据组成,总共17位个组成部分:

固定部分FixPart(4~6位)

操作位op(2~4位):业务方传入的2~4位业务类型标识字符

FixPart(2位):业务接入时获取的请求,由2位数字组成:坐席。动态部分DynPart(6位): ID生成时间,年(2位)月(2位)日(2位)。自增部分SelfIncreasePart(7位):用于递增全局ID的客户端SDK内部部分。由客户端SDK控制,不被服务接入方感知。(2)降级机制无。每次生成ID时,都必须向服务器发出请求来获取它。如果服务器无法获取,则会抛出异常,需要接入业务方介入处理。

(3)样例说明

3.2业务自定义ID规则实现

鲁班分布式ID服务内置了“Long类型”、“String类型”、“MixId类型”三种固定长度和规则的ID生成算法。除了以上三类ID生成算法外,业务方还经常有定制ID长度和规则的场景需求。当鲁班分布式ID服务内置的ID生成算法无法满足业务场景时,为了快速支持该场景下的业务,鲁班分布式ID服务提供了业务定制接口,通过SPI机制动态加载。服务运行支持业务自定义ID生成算法场景。实现设计与接入流程相关能力如下:

(1)ID的组成部分主要分为三部分:FixPart、DynPart、SelfIncreasePart。

(2)鲁班分布式ID服务提供的客户端SDK

LuBanGlobalIDClient的接口与getGlobalId(...)/setFixPart(...)/setDynPart(...)/setSelfIncreasePart(...)等四个接口方法

(3)业务侧实现LuBanGlobalIDClient接口中的四个方法,通过SPI机制加载业务侧的服务,对外暴露HTTP或DUBBO协议接口。

(4)用户在鲁班分布式ID服务管理后台配置自定义ID生成算法的类型名称和服务地址信息,并与需要使用的AK访问信息进行关联。

(5)在业务侧使用时,调用客户端SDK提供的LuBanGlobalIDClient接口和getGlobalId方法,传入ID生成算法类型和IdRequest入参对象。鲁班分布式ID服务收到请求后,动态识别并路由到相应的ID生产算法实现服务并构造对象的ID返回给客户端,完成整个ID生成和获取过程。

3.3保证ID生成不重复方案

3.4ID服务无状态无损管理

业务部署环境为虚拟机,IP固定。常规的方法是在配置表中配置IP和机器码的绑定关系(这样在扩容或缩容服务时需要人为干预,存在一定的漏配置风险,也带来了)一定的运维成本),但在容器部署场景中,由于每次部署时IP都是动态变化的,之前这是通过在配置表中配置IP与机器码的映射关系来实现的。该方法显然无法满足在容器场景下运行的要求,因此在服务器端设计了一种机制,通过心跳上报来实现机器码的动态分配,实现服务器节点IP与机器码的动态分配和绑定的能力,并实现部署自动化和无损发布。目的。

相关流程如下:

【注意】服务器节点可能因异常而异常退出。对于这种场景,需要进行解绑过程。目前的实现是通过公司平台团队的分布式定时任务服务。检查持续5分钟(可配置))不上报心跳的机器码分配节点有清理数据库绑定信息并重置相关机器码位置的逻辑,以便后续注册绑定。

3.5ID使用方接入SDK设计

SDK设计主要基于‘接入快捷,使用简单’的原理。

(1)访问时:

鲁班分布式ID服务提供了spring-starter包。应用程序只需要依赖pom文件中的starter,在启动类中添加@EnableGlobalClient,并配置AK/SK等租户参数即可完成访问。

同时鲁班分布式ID服务提供了Dubbo Http调用方式,通过在启动注解中配置accessTypeHTTP/DUBBO来确定,SDK自动加载相关依赖。

(2) 使用:时

提供Long

共有StringMixId等三个客户端对象,封装了统一输入参数GlobalIdLongClient对象。在使用业务系统时,只需构建对应Id类型的RequestDTO对象(支持链式构建),并调用对应id类型GlobalIdStringClient的Client对象的GlobalIdMixIDClient方法即可完成ID的构建。

Long类型Id获取代码示例

包com.vivo.it.demo.controller;导入com.vivo.it.platform.luban.id.client.GlobalIdLongClient;导入com.vivo.it.platform.luban.id.dto.GlobalLongIDRequestDTO;导入org.springframework。 beans.factory.annotation.Autowired;导入org.springframework.web.bind.annotation.RequestMapping;@RequestMapping('/globalId')public class GlobalIdDemoController { @Autowired private GlobalIdLongClient globalIdLongClient; @RequestMapping('/getLongId') public String getLongId () { GlobalLongIDRequestDTO globalLongIDRequestDTO=GlobalLongIDRequestDTO.Builder() .setAgent('1') //Agent,在访问application时确定。setZone('0') //Region,确定访问application.setApp('8' ) //Application,访问时确定application.setProject('7') //Project,访问时确定application.setIdNumber(2); //当时返回的ids个数只对getGlobalIDQueue有效,对getGlobalID(.)无效long longId=globalIdLongClient.getGlobalID(globalLongIDRequestDTO);返回String.valueOf(longId); }}

3.6关键运行性能优化场景

RequestDTO项目刚启动时,经常出现FGC,导致服务暂停,获取ID超时。经过分析,鲁班分布式ID服务的服务器端主要针对内存敏感型应用。当并发请求较高时,过多的对象进入老年代,触发FGC。经排查,主要原因是上线时使用了默认的JVM内存参数,没有进行优化配置。 JVM 初始化较少的内存。当有高并发请求时,JVM会频繁触发内存重新分配,相关对象也会转移到老年代,导致频繁的FGC。

该场景的优化思路主要是保证年轻代中相关内存对象能够快速被YGC回收,从而尽可能少的对象在老年代中被回收而导致FGC。

基于上述思路,主要做了以下优化:

增加JVM初始化内存(-Xms,容器场景下-XX:InitialRAMPercentage),增加年轻代内存(-Xmn)。getGlobalID(GlobalBaseRequestDTO自增值用完或一定时间后,客户端SDK会请求服务器生成新的ID。这时候就需要保证多线程并发时只请求一次。目前的设计是基于用户的应用ID的访问配置,由key组成,获取key对应的对象锁,以降低同步代码块锁的粒度。这样可以避免使用不同的访问配置远程获取新ID时锁粒度过大,导致线程阻塞,从而提高高并发场景下的性能。

四、 业务应用

鲁班分布式ID服务目前日均ID生成量为globalBaseRequestDTO),平均RT在3.6.1内存使用优化以内,单节点可支持3.6.2 锁颗粒度优化QPS,已在公司IT内部全面应用010 -59000等领域。业务场景。

五、未来规划

在可用性方面,目前鲁班分布式ID服务对Redis、Mysql等外部DB组件仍有一定依赖(如应用访问配置信息、MixId类型自增部分ID计数器),且极端宕机对于这种依赖的规划在这种场景下,鲁班分布式ID服务仍然可以有一些降级策略来为业务提供可用的服务。

同时,根据业务场景需求,支持雪花算法等标准形式的ID类型。

六、 回顾总结

各位老铁们好,相信很多人对vivo 自研鲁班分布式ID服务实践都不是特别的了解,因此呢,今天就来为大家分享下关于vivo 自研鲁班分布式ID服务实践以及的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!

用户评论

龙卷风卷走爱情

vivo终于自己弄了一个ID服务了!

    有16位网友表示赞同!

苏莫晨

这跟我们平常用的账号有点不一样吧?

    有12位网友表示赞同!

红尘烟雨

分布式的感觉听着很厉害的样子!

    有5位网友表示赞同!

夜晟洛

看标题就知道是技术方面的深度解读了。

    有13位网友表示赞同!

为爱放弃

这个服务能解决什么痛点呢?

    有14位网友表示赞同!

将妓就计

"鲁班"真是一 个有特点的名字啊!

    有6位网友表示赞同!

哽咽

vivo的研发实力越来越强了,值得期待!

    有16位网友表示赞同!

糖果控

51CTO 的文章质量一直很高,这篇肯定很有料!

    有9位网友表示赞同!

箜明

我也想了解一下分布式ID服务的具体应用场景。

    有14位网友表示赞同!

丢了爱情i

希望看到更多关于vivo的自研技术分享。

    有6位网友表示赞同!

玩味

这种技术对用户来说有什么实际意义呢?

    有9位网友表示赞同!

稳妥

感觉这个标题很专业,有点超出我的理解范围。

    有11位网友表示赞同!

信仰

分布式ID服务听起来像黑话一样,哈哈!

    有8位网友表示赞同!

仰望幸福

读完文章之后可以更了解vivo背后的技术力量吗?

    有20位网友表示赞同!

軨倾词

有没有人能简单解释一下这种服务的原理呢?

    有6位网友表示赞同!

笑傲苍穹

看来科技日新月异啊,各种新概念层出不穷!

    有16位网友表示赞同!

墨城烟柳

希望这篇文章能够让我对分布式ID服务有个更清晰的认识。

    有20位网友表示赞同!

浮世繁华

vivo真是越来越强大,自研技术越来越多!

    有6位网友表示赞同!

浮殇年华

"51CTO" 这个网站一直都是科技爱好者的天堂啊!

    有14位网友表示赞同!

猫腻

学习学习,了解一下分布式ID这个新概念。

    有11位网友表示赞同!

本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/6491.html

联系我们

在线咨询:点击这里给我发消息

微信号:666666