引言
闲鱼是一个以C2C为主的平台,区别于B端的用户,C端卖家在发布商品时更倾向于图+描述的轻发布模式,对于补充商品的结构化信息往往执行力和专业程度都不高,这为我们的商品理解带来了很大的困难。为了能够在发布侧获得更多的商品结构化信息,我们开始尝试在原有图+文的极简发布模式中加入商品关键属性的补充选项,事实证明,适当的结构化属性选项并不会影响用户的发布体验,却能极大地提升我们对商品理解的能力。然而存在以下问题:
在设定结构化属性选项时,往往强依赖行业运营的经验,缺少实时的、多维度的数据分析手段。虽然离线产出的数据报表能够在一定程度上统计某些关键指标,但对于精细的、个性化的数据查询需求,离线报表扩展性和性能都不足。
基于上述问题,我们搭建了龙宫数据分析平台。
龙宫数据分析平台的定位与总体框架
区别于数据报表,我们在设计龙宫数据分析平台时主要考虑了以下方面:
- 实时性要求,当运营上线新策略或因服务问题线上出现数据波动时,我们希望能够实时地分析出结构化类目属性在这段时间内的覆盖情况,以帮忙运营做进一步的决策。
- 多维度要求,闲鱼目前拥有8000+的叶子类目,不同行业运营的侧重点各不相同,数据分析平台要能够满足个性化的数据分析需求。
- 数据管理要求,闲鱼的类目属性、SPU数据、运营策略需要一个统一管理的地方。
我们希望以此实现结构化数据对运营的反哺,构成商品结构化数据生产与应用的闭环。
总体分层框架如下:
数据链路建设
构建数据分析平台的关键是数据链路的建设,在闲鱼,结构化数据主要分为在线数据(通过发布、编辑入口用户直接填写的数据)和离线数据(通过后置算法模型分析商品的图文获取的数据)。数据链路的建设存在以下关键难点:
- 存储数据量大(全量20亿+),访问QPS高(1.5万+),服务稳定性要求高。
- 数据来源多(10余种),各来源数据异构,存在重复、冲突的数据,数据实时性要求高(秒级延迟)。
- 数据分析场景复杂(QPS小,但sql复杂度高),普通数据库查询难以支撑。
针对数据量大和QPS高的问题,我们选用tableStore作为存储商品结构化信息的数据库,它一种典型的列存储数据库,具有扩展性好、可用性高、单机可支撑QPS上万的特性,非常适合作为大数据的存储终端。其可用性可达99.99%,同时具有主备双库能力。
同时我们在线数据存储在mysql的商品表中,通过在java应用中监听表的变更将数据写入数据源表;离线数据通过ODPS+MQ的方式将数据传入算法模块,并通过blink将算法结果写入数据源表。由于在线离线的多来源数据可能存在重复、冲突的问题(同一商品算法A识别为iphone 12而算法B识别为iphone 11),所以在系统设计时我们使用源表来存储所有的原数据,使用终表来存储加工融合之后的数据,加工融合的策略是产品、运营可决策的。
分析数据我们使用的是分析型数据库ADB,ADB在存储容量、单机查询QPS方面都远不及tableStore,但它在复杂sql的运行、实时索引创建、冷热数据隔离等方面拥有其他数据库不及的性能,是数据分析库的较好选择。
离线异构数据源的接入
在闲鱼,结构化数据不仅仅来自于发布时的卖家填写,正如前面所说,闲鱼的C端卖家在填写结构化属性的专业程度和执行力都远远不及淘宝天猫的卖家,所以我们通过图文多模态的算法,在发布的后置链路中为商品补充很多结构化的属性(这部分cpv目前占大盘覆盖率的一半左右,不同类目情况不同)。接入这些离线数据具有以下难点:
- 各个数据具有结构不同、产出时间不同、数据量级大的特征,难以复用相同模式,接入新数据源的成本高。
- 数据同步任务分散,难以做统一监控。
针对这些难点我们设计了一套离线异构数据源统一接入的方案:
各个算法的离线数据存储在ODPS中,各个算法的数据格式不一样,数据的分区也不同,所以先通过一个ODPS的同步任务将各数据源数据统一到一张结构化标准标签表idle_kgraph_std_source中。表结构如下:
key | json格式的数据,key为主键列名,value为主键值 |
---|---|
data | json格式的数据,每个key对应tableStore源表中的一列,value为需要写入该列中的值 |
scene | 分区字段,该数据来源于何种场景 |
source | 分区字段,该种场景下的数据来源 |
表中key为主键信息,因为不同场景的数据主键不一样,所以这里设计为开放式的主键,数据为json格式,key为主键列名,value为主键值。结构化标准表idle_kgraph_std_source通过一个Blink任务实时同步到tableStore的各个场景的数据表中。在Blink任务中,根据scene和source字段将数据进行分发,根据data中的key将数据路由到tableStore表中的不同列。同时为了提升效率,减少在Blink任务中写数据库的次数,拿到数据后,先对数据进行合并操作,将同种场景(例如结构化属性数据)的多来源数据合并成一条,再进行写操作。
通过这套方案,我们成功解决了多数据源接入中数据难以收口,难以统一监控的问题,同时,数据标准表中开放式数据格式的设计使得新数据源能够快速接入,极大地降低了重复开发的成本。
数据加工融合
在获取到多来源数据之后,我们需要对数据进行加工融合,融合的策略是由产品和运营共同决定的,在变更策略时,存量的商品数据也需要重新进行加工融合,所以数据加工融合链路必须具备增量处理稳定,全量处理快速的特点。
在进行全量处理数据时,利用分布式任务调度系统,主任务节点通过数据库的分片将全量数据划分成多份,并将数据索引下发给各个子任务节点,由子任务进行数据拉取,使数据拉取与处理不受数据库的物理分区与通道限制,大大提升性能,目前6亿全量数据处理仅需40min。任务的分发策略如下:
总的来说,主要解决以下问题:
- 分布式任务分发,分布式完成全量任务。
- 操作幂等,操作可以重复,但不影响最终结果。
- 全量增量彼此隔离,不影响在线服务
数据分析模块设计
在数据分析的场景中,大量涉及到正逆排序、按某指标过滤的频繁查询,如果对每一次数据分析请求都做一次完整的数据查询,对数据库会造成较大压力。
所以设计数据分析模块时,我们将请求的分析条件分为两类:
- 维度分析条件:根据不同的维度,需要运行不同的查询逻辑。会通过一个Distributor将分析请求路由到不同的processor中执行。
- 筛选排序条件:这些条件不影响查询的逻辑,只会在查询的结果中进行排序或过滤,针对这种情况我们会优先从缓存获取结果,并在内存中进行排序过滤,以提升分析性能。
基于上述的方案,可有效降低数据分析查询的成本,使查询平均效率提升50%以上。
效果
目前龙宫平台已推广至行业运营、闲鱼搜索、闲鱼首页推荐等场景,取得了阶段性效果:
- 为行业运营提供8000+叶子类目属性维度的数据分析,助力运营决策结构化选项在闲鱼主发中的透出,帮忙其为闲鱼结构化大盘贡献8成类目覆盖,一半核心cpv覆盖。
- 为搜索、推荐等场景提供快捷的查询手段,帮助开发、算法同学实时定位线上问题,实现秒级延迟。大大提升了badcase归因定位效率。
展望
我们致力于将龙宫打造成一个全面、灵活、准确的商品理解数据平台,接下来我们将主要针对以下方面继续优化:
- 与商品发布、成交大盘对接,接入商品诊断能力,提供更多维度的数据分析能力,推广场景覆盖,助力更多的产品、运营快速决策。
- 增加更多、更直观的数据表现形式,优化界面与UI设计。
- 增加用户维度的数据分析能力,与算法对接,将数据分析的结果反哺算法,使得算法模型能预测出准确、个性化的类目属性。