关于app:京东APP百亿级商品与车关系数据检索实践-京东云技术团队

165次阅读

共计 3482 个字符,预计需要花费 9 分钟才能阅读完成。

导读

本文次要解说了京东百亿级商品车型适配数据存储结构设计以及怎么实现适配接口的高性能查问。通过京东百亿级数据缓存架构设计实际案例,简略分析了 jimdb 的位图 (bitmap) 函数和 lua 脚本利用在高性能场景。心愿通过本文,读者能够对缓存的内部结构常识有肯定理解,并且可能以最小的内存应用代价将位图 (bitmap) 灵便利用到各个高性能理论场景。

1. 背景

整个汽车行业行特殊性,对于零配件有一个很强的对口个性,不同车应用的零配件(例如:轮胎、机油、三滤、雨刮、火花塞等)规格型号不一样。在售卖汽车零配件的时候,不能像 3C 家电、服饰,须要联合用户具体车辆信息,举荐适宜的配件商品。基于此起因,京东自建人车档案模型并且利用算法荡涤出百亿级的车型 - 零配件的适配关系数据,最终造成“人 -> 车 -〉货 ”关系链路,解决“ 人不识货”的问题。具体应用场景如下图:

.

图 1.1 京东商详举荐商品 图 1.2 京东加购弹窗举荐商品

2. 数据模型

人 -\> 车 -> 货”关系的外围链路是由人(京东用户)、乘用车和 SKU 这三局部组成。

首先,用户在京东 APP 的商搜页、商详页多个地位都能够抉择本人的车型信息进行绑定(例如:图 2.1,京东商详绑车入口地位“+ 增加爱车”按钮),建设“人车档案”数据。

.

图 2.1. 京东商详绑车入口地位 图 2.2. 京东商搜绑车入口地位

其次,经营在后盾管理系统中将商品与车型进行绑定,建设“商品与车型关系”数据(商品与车型的关系数据量级在百亿级别)。

最终,购买商品的时候,京东举荐零碎能够通过用户本人绑定的车型举荐出适宜该车型的商品。具体商品适配车型数据模型,见图 2.3

图 2.3 京东商品适配车型数据模型

3. 缓存结构设计

基于后面两个局部的介绍,咱们能够理解到整个商品搜寻适配举荐存在两个最外围问题。第一、百亿级商品适配车型数据的存储结构设计,尽可能的占用资源老本最小;第二、商详通过用户车型来搜寻适配商品时,必须保障接口性能的 TP99 位于毫秒级。最终技术选型的时候,采纳了 jimdb 的位图 (bitmap) 函数来进行数据存储。

3.1 位图 (bitmap) 构造

位图 (bitmap) 是通过最小的单位 bit 来进行 0 或者 1 的设置,示意某个元素对应的值或者状态。一个 bit 的值是 0 或者 1;也就是说一个 bit 能存储的最多信息是 2。

• 位(bit):计算机外部数据存储的最小单位,例如:11001100 是一个八位二进制数。

• 字节(byte):计算机中数据处理的根本单位,习惯上用大写 B 来示意,1B(byte, 字节)=8bit。

图 3.1 位图 (bitmap) 内部结构

3.2 位图 (bitmap) 数据写流程

位图 (bitmap) 是基于 jimdb 的 SDS(简略动静字符串)类型的一系列位操作,遵循 jimdb 的 SDS 个性,例如:位图 (bitmap) 最大长度 512M,最大能够存储 232 位。以下是“big”字符串的 SDS 构造示例:

图 3.2.1“big”字符串的 SDS 构造

SDS(简略动静字符串)为了保障性能采纳了空间预调配的策略:空间预调配用于优化 SDS 的字符串增长操作。SDS 的 API 对一个 SDS 进行批改并且须要对 SDS 进行空间扩大的时候,程序不仅会为 SDS 调配批改所必须要的空间,还会为 SDS 调配额定的未应用空。具体预调配流程图如下:

图 3.2.2SDS 预调配流程图

地位 1:创立 SDS 简略字符串预调配空间为:偏移量 /8+1。

地位 2:残余空间有余时,预调配空间流程。

3.3 压缩商品与车关系缓存

偏移量(自增 ID)全量车型商品 SKU
11165788101362
21165793101362

商品适配车型关系(百亿级数据量)

商品与车关系缓存存储过程中,采纳了商品 SKU 作为 KEY,全量车型 ID 的偏移量 (采纳偏移量是为升高内存耗费) 作为 VALUE 值来进行存储。

全量车型 ID 大概有几十万的数据量,极限状况下一个商品 SKU 能够适配几十万辆车,很容易造成缓存大 KEY 的问题,为此咱们进行了偏移量(全量车型 ID 对应的自增 ID)的分段解决。具体是依照:SKU 作为缓存 KEY 的根底上,追加一个分段标记数字作为新 KEY,每个偏移量都会依照分段范畴对应一个分段标记数字。例如:偏移量 1~50000,对应缓存 KEY 为 SKU+0;偏移量 50001~100000,对应缓存 KEY 为 SKU+1,其它偏移量以此类推,这样就保障了一个 SKU 即便适配所有车辆也不会呈现缓存大 KEY 的状况。

BitMap 缓存构造底层应用 SDS 简略字符串,为了保障性能采纳了预调配空间的策略(图 3.2.2,“缓存 BitMap 外部存储流程图”的“地位 2 ”中虚线框圈选),这样在缓存商品与车关系的时候节约了大量的缓存空间。为此咱们调整了偏移量存储程序,首先获取到须要缓存的车型内最大的偏移量,保障同一个缓存 KEY 第 1 次创立 SDS 简略字符串(图 3.2.2,“缓存 BitMap 外部存储流程图”的“地位 1 ”中虚线框圈选)后,不再进行第 2 次空间扩容,这样来最大限度的晋升缓存利用率,起到压缩空间目标。缓存数据关系流程如下:

图 3.3.1 缓存数据关系流程

地位 3 : 设置分段最大的偏移量,保障后续新增偏移量不再扩容空间。

地位 4 : 设置分段较小的偏移量。

全量车型 ID 是定长 7 位的数字,如果用它作为偏移量将耗费内存微小,所以采纳对应自增 ID 作为偏移量。最终在 bitmap 缓存的商品 SKU 与车的适配关系缓存构造如下图:

3.3.2 商品与车缓存结构图

地位 5 :spuId 用 {} 括起来示意缓存路由(Lua 脚本中同一次申请,数据必须在缓存同一个分片上,否则会失落数据)。POP 商品 spuId 是 SKU 的产品 ID,自营商品 spuId 是 SKU 的 MainSkuId。

备注:

1、自营商品 MainSkuId 可能发生变化,所以咱们接入了商品变动 MQ 音讯,实时调整 SKU 与车适配关系的存储地位。

2、京东商详页面中每个不同的规格 / 型号别离对应不同的 SKU,然而它们都对应同一个 SpuId 或者 MainSkuId。

4. 缓存架构设计

商品与车的关系数据量每天都在一直增长,要求缓存架构设计,须要反对集群横向 / 纵向扩容和来满足业务倒退以及高可用性。整个缓存架构体系次要有前端、京东养车商品与车关系层和存储三局部组成。

“商品与车关系缓存架构”层外围包含:1、“集群路由”层,实现了集群横向扩容,保障数据量增涨的时候,缓存容量也能跟上。2、“分片路由”层,保障搜寻的底层数据的分片雷同,防止数据失落。

“存储”层外围包含:1、实现了缓存压缩,参见 3.3 压缩商品与车关系缓存。2、单元化实现跨区域灾备,保障大促零碎稳定性。具体商品与车关系缓存架构如下:

4.1 商品与车关系缓存架构图

地位 6 : 集群路由,通过商品类型或者商品编号 (POP 商品) 路由到不同缓存集群,便于横向扩大,每个集群单分片限度,解决分片超过限度问题。

地位 7 : 分片路由,保障 Lua 脚本搜寻数据的底层数据集群分片雷同,防止数据失落。其中自营商品和 POP 商品的路由别离是 main\_sku\_id 和 product_id。

地位 8 : 自营商品缓存集群,单元化实现跨区域灾备,采纳自研 DRC(Data Replication Center)数据同步机制。

地位 9 :POP 商品缓存集群,通过商家编号拆分为两个子集群。

5. 高性能搜寻

基于 BitMap(位图)缓存的商品与车关系数据,商详调用接口的外部实现采纳了 Lua 脚本来升高网络开销,保障整个接口的性能。以下是搜寻接口的流程图:

5.1 商详搜寻商品与车适配关系流程图

地位 10: 商详调用接口的时候,要传两个参数。第 1 个参数是全量车型 ID 列表,大概 5 个全量车型 ID。第 2 个参数是商品 SKU 列表,SKU 的数量极限超过 200 个。最初全量车型 ID 与商品 SKU 组合为上千个商品与车的关系后,再到百亿级适配关系去搜寻看是否匹配的。如果不匹配返回适配商品,反之则返回不适配。

Lua 脚本缩小了应用服务器与缓存服务器的交互,升高了网络开销的工夫,达到晋升搜寻服务的性能。以下是 Lua 脚本具体代码:

5.2 商详搜寻商品与车适配关系 Lua 代码

基于以上缓存设计和 Lua 脚本的应用,整个接口 T999 小于 13ms。具体的接口性能监控如下图:

5.3 商详搜寻商品与车适配关系接口性能

6. 总结

整个缓存结构设计的时候,应用 BitMap(位图)来存储数据。解析 SDS 的外部存储流程,通过存储流程机制避开预调配空间节点,最大限度的利用缓存空间,防止资源节约。采纳 Lua 脚本来实现数据的适配搜寻,升高网络开销,进一步晋升接口的性能。心愿此文对大家后续设计相似场景有肯定的帮忙和启发。

作者:京东批发 张强

内容起源:京东云开发者社区

正文完
 0