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

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

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

用户通过在线查询服务把此查询条件传入时,查询服务检测到入参是IdleUnisearchBaseSearchParams的之类,会根据命名规则使用反射机制判定unisearch_includeCollection_prefix_poiCode是需要对业务源表的poiCode字段做include(包含)查询,然后从元数据注册中心的映射关系数据取出poiCode对应的预留表字段名为dima_a_long_r1,构造Search Planner查询串,执行后续查询动作。

当引擎返回查询结果后,网关查询服务再次根据元数据注册信息,利用反射对引擎结果DO进行翻译转换,包装成下面所示的poi业务专用DO后返回给业务开发同学。

  1. public class UnisearchBiz1001SearchResultDo extends IdleUnisearchBaseSearchResultDo { 
  2.     private Long poiId; 
  3.     private Long poiCode; 
  4.     private String poiName; 

通用搜索预留表一共有8张,全部字段加起来是比较多的。如果把字段全部召回,实际上大部分字段都是业务没有进行注册的空字段,返回数据会比实际需要的数据大小膨胀几十倍,网络传输开销、大量空字段反序列化开销、DO字段转换开销会导致在线查询服务的RT很高。解决此问题比较简单,我们把整个在线召回流程定义为两个阶段,第一个阶段只根据用户的查询条件在引擎中召回符合要求的数据主键rawpk;第二阶段根据此rawpk列表去获取对应数据的summary(即所有字段的信息)时,利用引擎支持的dl语法,要求二阶段仅返回用户注册过的预留字段即可。当然,这些工作也由我们在通用搜索系统的网关代码中提前实现了,对各业务接入同学透明。

增量问题的特殊解法

到现在为止一切看起来都很完美,貌似我们已经用这套系统完美解决了数据导入、转换、bs、查询等一系列工作的自动化包装,业务同学需要做的仅仅是来我们的业务注册中心界面上登记一下而已。不过实际上在表面之下还隐藏着一个较严峻的问题,就是大增量的问题。

由于与BuildeService直接对接的是结构已经固定的通用搜索预留表,也就意味着原生的dump层数据源结构是不可能变化的,唯一能变化的是从业务源表经过精卫系统写入通用搜索预留表的数据。当上游有一个新业务接入进来时,如果它的源表数据量达到了十亿级别,按照目前精卫能够达到的迁移速度,也就意味着通用搜索预留表的更新TPS能够达到5万的级别,而这每秒5万条数据更新的压力就会直接打在实时BS系统上,即引擎需要每秒更新5万条doc数据才能保证搜索结果与源表数据的一致性。而搜索引擎的实时BS能力依赖于实时内存的容量,这么大的增量TPS会在短时间内打满实时内存,导致源表后续的更新数据无法实时被BS构建成索引,那么搜索系统就无法搜索到新的业务数据(包括新增、更新、删除的数据),称为增量延迟问题。

多个业务共享这套引擎服务,线上已经在提供搜索服务的业务无法接受增量延迟;而对本次新接入的业务来说,在第一次接入时把数据往通用预留表同步的这段时间内,数据搜索不到是完全可以接受的。因此,我们想出一个办法实现了线上存量业务的增量数据正常实时进引擎,而新业务的全量迁移数据引发的增量不实时进引擎。具体实现分为以下几个步骤:

1、通用搜索预留表按照db表的创建规范,都会有一个gmt_modofied字段,类型为datetime。当预留表中的数据发生任何变化(增、删、改)时,gmt_modofied字段都会更新为本次操作的时间戳。这个逻辑在精卫迁移任务的DAO层实现。

2、为通用搜索预留表的每一张表额外增加一个datetime类型字段,命名为gmt_drop_inc_tag。精卫全量任务为新业务导数据时,我们在精卫任务启动参数中带上“drop_inc_tag=true”的标识,相应地我们在精卫自主消费代码中识别到这个标识后,会在完成数据转换生成的DAO层入参DO中把gmt_drop_inc_tag字段赋值为gmt_modofied一样的值,然后写入DB。而非新业务全量和增量精卫任务的启动参数中无“drop_inc_tag=true”的标识,则其他业务的增量精卫任务写入DB的记录中只会更新gmt_modofied而不会更新gmt_drop_inc_tag字段。

3、在引擎原生dump层,我们在每一张通用搜索预留表与后续merge节点之间增加一层udtf逻辑代码。这里的udtf代码是dump层对外开放的一个口子,允许引擎接入方在dump流程上对数据做一些特殊处理,每一条上游的数据都会经过udtf的逻辑处理后再输出到下游进行merge、join、输出给BS系统。我们在这里实现的逻辑是,如果识别到当前是全量dump流程,则把当前流入数据的gmt_drop_inc_tag置为空,然后向下游输出;若识别到当前是增量dump流程,则检查当前流入的数据其gmt_modofied字段与gmt_drop_inc_tag字段是否相同,若两字段相同则对此数据执行drop逻辑,若两字段不同则把当前流入数据的gmt_drop_inc_tag置为空后向下游输出。所有被执行了drop逻辑的数据都会被dump系统丢弃,不会输出到最终产出的数据文件中。

如此一来,老业务的增量数据都任然正常经过dump流程后通过BS(BuildServcie)系统实时反映到搜索在线服务中。而本次新接入业务的全量迁移数据都只是从业务源表迁移到了搜索预留表中,BS系统完全感知不到这批数据的存在。待新业务的数据已经全部从源表迁移到预留表之后,我们对引擎服务触发一次大全量流程,即先以全量dump的方式把通用搜索预留表的数据全部重新走一次dump逻辑,产出完整的HDFS数据,然后离线BS系统批量对此HDFS数据构建索引,然后加载到searcher机器提供在线服务。随后,对新业务开启精卫增量迁移任务,保证业务源表的变更实时反映到引擎中。

pic6

效果

(编辑:济源站长网)

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

热点阅读