接上篇:https://developer.aliyun.com/article/1225878?spm=a2c6h.13148508.setting.20.595d4f0eudDbz0
二、 然后,优化它:闲鱼搜索系统时效性优化
1. 差异化场景
上一章节提到的搜索系统架构适用于大部分电商平台,但闲鱼搜索场景与常规电商平台之间,又存在着显著差异。
其中,闲鱼商品单库存,无明显冷热差异且变更频繁的特性,对全链路的实时处理能力都提出较高的要求。试想一下,热门的商品被买下架后,并没有及时同步引擎。对买家、卖家和平台来说都是一种困扰与损失。
闲鱼搜索经年累月的业务迭代,累积了相当量级的实时增量。最严重的时期,引擎的增量延时一度达到8小时之久,对用户体验、成交效率形成了巨大冲击。因此过去的一段时间,我们开启了搜索时效优化的专项。
2. Searcher扩列
排查链路实时处理能力的瓶颈,如上文离线模块中对实时增量的描述(数据产出方实时生产的数据经中转Topic实时发送至Ha3,由Ha3引擎内的BS_lib构建出实时索引加载使用),在实时增量到达索引所在searcher列之前都未出现延时,因此瓶颈位于在线searcher的BS_lib的消费能力,最直接的方式是提升searcher的处理能力。因此,我们将searcher的列数从16列扩大至24列,提升了50%的实时增量处理能力,增量延时缓解。
3. 引擎架构治理
我们重新思考了闲鱼主搜引擎的架构与定位。在之前的架构中,倒排、正排、详情字段部署在同个引擎(Ha3引擎支持这种能力)。倒排、正排用作查询索引,详情字段补充商品详细信息,并对外提供信息补全服务。但查询的请求量是极其不对等的,详情字段的qps为索引字段的5.3倍。倒排与正排字段的数量远大于详情字段,因此查询请求的机器要求是小CPU,大内存,详情请求的机器则是大CPU,小内存。
两类字段部署在同一引擎,各自的资源短板被放大。同时,各字段实时增量是累加的。因此,我们拆分了查询引擎与详情引擎,缓解增量压力的同时,机器资源消耗也有所降低。
4. 增量分级
做了以上两个优化后,增量延迟有所缓解,但整体的增量量级并没有下降多少。因此在离线链路中,我们开发了增量Profile插件,用来统计字段修改的频率。
其中两个字段合计占到修改量的37%(总400+字段),经排查,两个字段并不需要秒级的实时性。引擎的离线链路中,虽然设定了批次增量与实时增量,但事实上所有开启的增量都会走实时增量通道,挤占优先级更高的增量的吞吐量。因此,进入引擎的增量务必根据业务诉求再做一次分级。
由此,我们在buildService上开发了增量分级插件,提供增量分级处理的能力,对于准实时性要求的增量仅做批次增量(1小时进引擎),不挤占核心实时增量的通道,保障商品核心特征的实时性。
5. 辅表写扩散问题
优化增量量级的另一个重要关注点就是辅表写扩散问题。商品以item_id为主键分列部署,离线阶段,当辅表有驱动增量时,跟主表join后增量翻倍增长。例:商品上挂载用户在线状态的特征,当用户状态变化时,该用户的所有商品都会发出实时增量消息。量级将远大于用户在线状态的实际消息量级。解决方式是将这一类字段,单独改造成在线辅表,通过在线join的方式查询。
经过以上系列的优化后,我们最终把引擎延迟抹平,达到真正实时化搜索的定义(基本无延迟,红框部分为全量后追增量阶段,采用逐行Rolling模式,切换中机器不服务,对用户体验无感知)。
三、 最后
电商平台的搜索是一项系统性工程,经过多年发展,已沉淀出一套通用性的框架。里面不仅包含对搜索引擎的理解,也体现服务端架构设计的可伸缩、平行扩展等概念。但仅有框架的认知还不足以支撑快节奏的互联网业务发展。在通用框架的基础上,深刻理解搜索业务,关注稳定性、研发效能,找到应用场景的痛点,有针对性的做出架构调整,才能构建出真正助力业务发展的搜索系统。