加入收藏 | 设为首页 | 会员中心 | 我要投稿 济源站长网 (https://www.0391zz.cn/)- 数据工具、数据仓库、行业智能、CDN、运营!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

异构数据半小时实现搜索功能,一个系统搞定

发布时间:2019-08-28 21:51:27 所属栏目:优化 来源:峰明
导读:背景 对于闲鱼这种处于高速增长期的部门来说,业务场景在快速膨胀,越来越多的业务数据对搜索能力有诉求。如果按照常规的方式为各个业务搭建独立搜索引擎服务,那么开发和维护的时间成本将是非常巨大的。能否只用一套搜索引擎系统支撑不同业务场景产出的数

在一次典型的搜索请求场景中,用户以“iPhone6S”进行搜索,在搜索结果中用户除了希望看到商品基本信息如标题、描述、图片等,还希望看到存储在扩展表中的sku、扩展标签等扩展信息,以及卖家的昵称、头像、信用等级等用户维度信息。如何实现在一次召回过程把分散存储在多张表中的与同一个商品相关的信息都返回呢?这就需要在dump过程中把多表数据按照一定的方式组织起来,拼装成最终希望的宽表格式,再写入持久化存储供引擎构建索引。

我们在dump过程中,把与此业务场景相关的多张表按照主键做merge和join。同一维度内的多张表按照主键拼成大宽表的过程成为merge,比如1)和2)之间就是按照商品id做merge,结果记为M1;3)和4)之间就是按照用户id做merge,结果记为M2。结果M1中有一列数据是卖家的用户id,而M2的主键就是用户id,将M1和M2根据用户id做join,就得到了最终的大宽表,宽表中的任何一条数据都包含了1)2)3)4)中的完整场景信息。

在通用搜索预留表构建过程中,我们已经按照dima_pk+ima_b_inner_mergekey和dimb_pk+dimb_b_inner_mergekey的方式做维度内merge,按照dima_pk+dimb_pk的方式做维度间join的方式完成了预留表与BuilderService的对接。只要业务同学把源表数据正确迁移到预留表中,就可以实现上面描述的复杂dump流程。数据迁移既要保证源表的全部数据被迁移,也要保证线上实时增量数据被迁移,而且迁移过程中需要根据元数据注册中心的字段映射信息进行转换,这个流程还是比较复杂的,如何自动化实现这部分工作呢?

我们的实现方式是基于阿里巴巴内部的中间件平台“精卫”做二次开发,编写自主消费tar包上传到精卫平台运行,根据各业务的注册信息完成适用于各业务的迁移任务,这部分工作由我们在开发通用搜索系统时完成,对各业务接入同学完全透明。

精卫平台支持全量迁移任务和增量迁移任务,简单的理解全量迁移任务就是循环对源表执行“select * from table_xxx where id>m and id比如一个业务开发同学需要为小区POI数据接入搜索能力,他在注册中心注册这个业务,在mapping_info中声明需要把源表的poi_id映射为dima_pk,把源表的poi_name映射为dima_a_text_r1,环境为预发环境。配置完成后,系统会自动分配一个biz_code如1001。当精卫任务启动时,我们上传到精卫的自主消费代码会把从源表拿到的poi_id为123123123的数据转换为主键为“1001_0_123123123”的数据写入通用搜索预留表,其中1001代表业务唯一识别码,0代表预发环境,123123123代表原始业务主键。

pic3

如此一来就实现了用户只需一次填写,就自动化完成数据dump的工作。

4、在线查询服务

既然dump产出数据的字段是无语义的,那么相应的BuildService构建处端索引数据各字段也是无语义的。

这里看起来通过无语义的定义方式支持了将多场景异构数据写入同一个引擎服务,但是对业务开发同学来说太不友好了。他们在业务开发中调用搜索服务时,期望的方式是自然的业务语义调用,如下面的代码片段:

  1. param.setTitle("iPhone6S"); 
  2. param.setSellerId(1234567L); 
  3. result = searchService.doSearch(param); 

但是现在字段没了语义,他们开发的复杂度大大提升,甚至时间一长会陷入难以维护的境地,因为业务代码写完1个月后没人会再记得代码中的“param.setDimaALongR1(1234567L)”是什么意思,这是按照用户id还是商品id查询?

虽然底层我们是将多个业务的数据放在一个引擎服务中,但是我们希望提供给业务开发同学(也就是我们这套系统的用户)的在线查询服务与独立搭建一套引擎的体验是一样的。所以,这里就需要有一个翻译层,通用搜索系统接收到的查询请求是“title=iPhone6S”,我们需要根据元数据注册中心的映射关系自动翻译成“dima_a_text_multilevel_r1=iPhone6S”后再向引擎发起搜索请求,并把引擎返回的数据DO中无语义字段翻译成源表的有语义字段。

pic4

可以看到,通过我们提供的搜索网关二方包,业务同学可以按照有语义的方式设置查询条件“param.setTitle("iPhone6S")”,同时自动化把引擎返回的无语义字段进行包装成为有语义的字段。业务同学完全觉察不到中间的转换过程,对他来说就像在使用一个为他单独搭建的搜索引擎服务一样。

每个业务接入方的源表字段定义都不同,只写一套搜索网关代码肯定无法实现上面的能力。我们的方案是,当用户在元数据注册中心曾经接入一个新业务后,后台自动化生成生成为业务定制的二方包代码,其中包含了查询入参、返回DO、查询服务接口。

还是以poi数据接入为例,poi业务域的开发同学在元数据注册中心说明了他需要按照poi_name做文本模糊匹配,需要根据poi_code做包含查询、不包含的精确查询。根据此登记信息,我们为用户自动生成poi业务场景专用的查询服务入参,每个入参都是一定的规则拼接而成,网关在线服务拿到此参数后可以根据命名规则翻译成具体的查询串。参数命名规则如下图:

pic5

(编辑:济源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读