技术分享|电商数据接口|淘宝天猫京东商品API接口之数据同步

常见的数据同步/集成场景多发生于不同的存储系统、不同的存储格式,如从 mysql 同步数据至数仓、excel 或 csv 导入数据库中,但是众多数据同步解决方案很少涉及从 http 接口同步数据。

如淘宝、拼多多等电商平台,平台内部不同团队之间的数据打通,很多的开源数据集成工具可以满足。但是像三方卖家入驻电商平台后,就需要在电商平台注册自研应用,通过开放平台提供的接口打通自研应用与电商平台的数据壁垒,准确及时地获取到商品、订单、物流、售后以及评价等实时变更数据,而无法实现数据库级别的数据同步,让 datax 之类的大部分数据同步工具无法使用。

本系列文章描述笔者在实际工作中对接快手、淘宝等开放平台同步商品、订单、接口售后单等数据的一些个人经验总结和实践方案。

数据同步接口

根据数据量和实时性的不同需求,开放平台数据查询接口总共有 2 种形式:

  • 分页接口。比如获取仓库列表,平台类目列表等。

  • 支持时间范围查询的分页接口。比如订单列表接口,根据订单修改时间分页查询。

数据同步的难点也在于准确、实时地通过时间范围分页查询接口同步数据。

基本实现:分页请求

根据时间范围进行分页请求的基本实现,请求参数中带有开始结束时间加上分页参数。

请求参数 json 如下:

{
 "startTime": "2021-11-11 00:00:00",
 "endTime": "2021-11-12 00:00:00",
 "pageIndex": 1,
 "pageSize": 50 
}

响应结果 json 如下:

{
 "dataCount": 10000,
 "pageIndex": 1,
 "pageSize": 50,
 "datas": [...]
}

接入方在接入数据的时候可以根据时间范围、分页参数逐时间段逐页同步数据,确保数据不丢失。

时间类型

开放平台往往也会根据业务需求,提供不同类型的时间范围,比如订单场景,有订单创建时间,修改时间,支付时间,出库时间等。对于数据接入者来说来说,最喜欢的时间类型为修改时间,根据修改时间同步可以确保数据发生修改后实时地同步过来。

但是修改时间有个丢数据的陷阱:需要根据修改时间降序同步。

假设有数据在某个时间范围内从左向右按照修改时间升序排序,效果如下:

1 2 3 4 5    6 7 8 9 10    11 12 13 14 15    16 17 18 19 20

在同步这个时间范围内,如果 20 条数据没有发生任何修改,分页拉取第一页 1 ~ 5,第二页 6 ~ 10 等可以确保数据不会漏。

但是在拉取第一页 1 ~ 5 后,数据 5 发生修改,其余数据不变,拉取第二页时再按照修改时间升序排序,此时排序效果如下:

1 2 3 4 6    7 8 9 10 11    12 13 14 15 16    17 18 19 20

可以看到数据 6 被归到第一页中,之后拉取第二页时会从数据 7 开始,数据 6 被遗漏。

按照修改时间同步,需要分页请求多次才能同步完成时,中间数据发生修改会导致数据排序顺序发生变动,从而造成数据遗漏。

但是按照订单创建时间、支付时间等时间类型则不会,因为订单一旦创建或支付,对应的创建时间和支付时间不会发生变动。

解决思路就是从最后一页向前拉。

同样是上面的 20 条数据,在同步完最后一页数据 16 ~ 20 条后,数据 5 发生变更,同步倒数第二页时,同步到的数据为 12 ~ 16,逐步推进分页,在最后一次请求中同步到数据 1 ~ 6。

倒着拉不会出现数据遗漏的情况,但是可以看到数据 16 被重复同步,接入方需要做好数据更新的幂等性。

数据接入时需确定时间类型,会不会发生变动,以及排序顺序:

  • 开放平台根据修改时间升序排序时,接入方需要从后向前翻页;

  • 开放平台根据修改时间降序排序时,接入方需要从前往后翻页。

接口常见限制

开放平台为了保护接口安全,会对接口进行一定限制:

  • 开始时间结束时间相差不能过大以避免深翻页。比如不能超过 7 天

  • 只允许同步近期数据。比如订单类只允许同步 90 天内订单

  • 减少每次请求数据量。比如限制每页数据最多 100 条

  • 接口限流。限制接口请求并发和 qps

取消 dataCount 响应字段,改为使用 hasNext

对于关系型数据库的存储,如 mysql,返回结果中的 dataCount 和 datas 两个字段无法在同一条查询语句中获取,需要分别执行一次 count 和分页 select 请求才能获取 dataCount 和 datas

接口响应包含 dataCount 字段的目的是为了接入方能够计算何时终止分页请求,这是必要的,因为接入方需要能够确定何时终止分页,为此开放平台接口需要多执行一次 count 语句。

为支持接入方分页请求,在接口响应中返回 boolean 类型的 hasNext 字段,表示是否还有下一页,帮助接入方判断是否到达最后一页。

接口响应中不再返回 dataCount 字段,可以避免开放平台进行 count 查询,极大提高接口性能。

那么开放平台该如何确定 hasNext 的值呢?

可以在执行 select 语句时设置 size 为 pageSize + 1,如果查询语句返回数据量为 pageSize + 1,存在下一页,否则不存在。

这种接口设计请求参数不变,响应参数如下:

{
 "hasNext": true,
 "pageIndex": 1,
 "pageSize": 50,
 "datas": [...]
}

使用 hasNext 时需要开放平台根据修改时间降序排列,因为接入方无法实现从后向前翻页。

取消 pageIndex 入参,改用 cursor

分页接口普遍惧怕深分页,即 limit 100 offset 1000000,深分页不仅会拖累接口响应时间,还会对数据库造成较大压力,带来潜在的系统崩溃风险。

为了减少深分页,开放平台多会限制时间范围间隔,比如结束时间开始时间不能相差超过 7 天,但是这种方式只能减少深分页而无法彻底杜绝。

cursor 方案可以彻底避免深分页问题。

请求参数 json 如下:

{
 "startTime": "2021-11-11 00:00:00",
 "endTime": "2021-11-12 00:00:00",
 "cursor": "1639487400913_5",
 "pageSize": 50 
}

响应参数 json 如下:

{
 "hasNext": true,
 "cursor": "1639487400918_10",
 "pageSize": 50,
 "datas": [...]
}

交互时第一次请求时 cursor 为空不传入,之后每次请求传入响应中 cursor 值,直到 cursor 返回一个特殊标识,分页结束。

使用 cursor 避免深分页的原理在于 cursor 的构成形式:为 datas 的最后一条数据的 timestamp + id。

开放平台接口对 cursor 进行解析构建 select 语句:

select * 
from table 
where id > ${id} 
and time >= ${timestame} 
and time < ${endTime} 
order by time, id
limit ${pageSize} 

技术分享|电商数据接口|淘宝天猫京东商品API接口之数据同步_第1张图片

你可能感兴趣的:(数据库,java,linux,python,json,sql)