当前位置: 首页 > 科技观察

从0到1再到100蘑菇街搜索与推荐框架探索之路

时间:2023-03-14 14:05:06 科技观察

【.com原稿】丁晓明,昵称小宝,蘑菇街搜索技术团队负责人。2011年底加入蘑菇街,2013年开始负责搜索团队,见证了蘑菇街的蓬勃发展。搜索引擎与广告引擎、实时个性化推荐系统、基于开源Solr/ES深度定制的实时搜索平台等。小宝蘑菇街搜索技术团队负责人小宝在WOTA2017“电商大促背后的技术挑战”。与大家分享蘑菇街在搜索推荐中踩过的坑,以及探索路上的经验总结。我们的经验虽然不是业内最好的做法,但也是一步步从0到1再到100,希望大家能从中有所收获。搜索架构现状探索蘑菇街目前的搜索架构如上图所示,即蘑菇街目前的搜索架构,分为线上和线下两部分。在线部分的主要职责是处理在线搜索请求。离线部分的主要职责是处理数据流。在线请求链接如上图所示,是整个在线请求链接,主要分为五个链接:topn->qr->engine->finerow->display。第一步先请求进入topn系统,进行ab配置/业务请求链接配置。第二步请求进入二维码改写系统进行分词、同义词扩展、类别关联、插件等。第三步进入UPS用户个性化数据存储系统。第四步:派送层拿到UPS和QR的数据后,放入搜索引擎进行召回。搜索主要会经过一轮海选,海选的依据是文本相关性和产品质量。这样做是为了确保召回产品的质量总体上是可靠的。之后会进行多轮初选,过程中会应用更复杂的算法模型对海选结果进行排序。搜索引擎获得大约一千个级别的结果。第五步,粗分选结果进入细分选系统。精细分拣系统主要通过算法进行个性化分拣和实时预测。精排序和引擎类似,也支持多轮排序。经过系统的精细排序,最终将结果展现给业务层。蘑菇街的统一引擎系统如上图所示。左边红框是蘑菇街的统一引擎系统,包括用户个性化存储系统、精细化存储、商品引擎、广告引擎等。由于这种形式的维护成本特别高,图上展示的统一Zindex内核架构正确的。这个架构的底层是共享内存分配器,上层是可以支持不同数据结构的各种引擎,上层是索引管理。基于这种架构,不同的引擎可以根据自己的需要创建自己的索引。和这个架构相关的是我们的运维平台,它是基于公司的Docker虚拟化技术。它可以非常快速地支持创建索引,包括创建后对整个索引数据的管理。还有一个排序平台,用于提供算法配置变更服务。搜索架构离线部分的数据流向如上图所示,是离线数据流的情况。主要职责是数据流的处理。完整的指标数据分为算法数据和业务数据。算法数据参与排序,整个链路从前端ACM管理,再落到整个数仓。清洗后在数据平台上运行训练脚本,将得到的特征导入特征平台,然后同步到线上。业务数据的主要来源是DB,主要存储商品与店铺之间的数据。业务变更主要基于mysqlbin-log事件监控,变更后进行全量和增量的变更。日常的索引操作和增量都会全量流向MQ,然后通过业务组装推送上线。搜索架构探索蘑菇街搜索架构的演进主要经历了导购时期(~2013.11)、电商初期(2013.11~2014.11)、Solr主搜索(2015.4~2016.3)、主搜索C++(2015.8~2016.11)、平台(2017.1~现在)五个阶段。简化版蘑菇街目前的搜索架构为了更清晰直观的对比,我将目前的搜索架构简化为上图五层:业务、投放、排序、召回、数据流。接下来,让我们看看我们从最早的时候,一步步走到现在,都经历了怎样的演变。蘑菇街搜索架构导购期的架构如上图所示。是~2013.11导购时期的建筑。它分为三层:PHP代码中的业务+传递,Java搜索引擎Solr中的召回+排序和数据流。这个时期对分拣的需求不是很迫切,更注重产品整体的丰富性和新颖性。简单理解,畅销榜等于点赞数乘以10加收藏数乘以50,这是基于Solr改造实现的。电商转型初期(2013.11~2014.11),流量因为卖自己的产品而变得更有价值,工程师会想办法提高流量的效率。同时,用户行为也在增加,产生更多数据。另外,增量管理复杂,数据量大,Optimaize风险高,导购、广告、搭配等多类产品暴露等,最明显的挑战是有更多的排序特征,更大的数据,和更频繁的次数。在蘑菇街搜索架构转型初期,架构面临着这些挑战。当时的想法是把算法独立成一个单独的Java项目来计算分数。而百万种商品,百种分类,算法排名达到G级。这些排序数据需要在搜索引擎中使用。起效快,但问题是增量方式会导致索引碎片增加,给在线引擎的稳定性带来波动。因此,另一种方式是利用Solr进程中的堆外内存来管理这部分排序数据。综上所述,改造初期的整体解决方案是将算法分离出来,独立完成,尽快将部分分数同步到引擎中,使其生效。这样的方法在当时线上效果非常显着,但是随着时间的推移又出现了新的问题:规则解毒->LTR,需要更多的算法排序;排序灵活性约束:计算出的分数被离线推送到Solr;Solr内存压力:GC/segmentmerging;静态点,相关性差;相关问题大推广:搜索“雨伞”,伞纹连衣裙排在第一位;Solr主搜索整体结构针对这些新问题,(2015.4)Solr主搜索改造,支持Rank插件(Ranker->Scorer),可配置+动态,整体结构如上图。处理关联问题,增加QR体系,处理内存压力,做Solr升级(Docvalues),算法划分动态字段增量,投放方式逐渐形成Topn体系,连接不同的外部搜索场景。Solr架构解决了算法变化的关联和在线排序等问题,但新的问题是虽然用机器学习来排序,但当时主要是热模型,有很多个性化的需求模型。同时,不同的人必须有不同的排序结果,有更复杂的重新排序或拆分的要求。由于Solr实现机制的限制,只能做一轮排序,而且很难改变。另外,Solr整个索引结构非常复杂,二次开发成本高,在内存和性能上也逐渐暴露出很多问题。同时JavaGC也是一个难以逾越的鸿沟。当时需要多轮排序,除了做一些文字关联,还要做品牌相对于产品的权重,比如支持某些品牌,打散品类等,单次做不了轮排序,原方法只能将多轮合并为一个排序,但效果会很差。C++的主要搜索架构如上图所示。C++主搜索架构(2015.8~2016.11)已经上线。它已根据整体性能和排序进行了定制。它可以支持多轮排序。整个内存采用内存方式,由排序系统支持。总体来说,这个阶段是比较完整的。每一层和整个系统都已经成型,但是在数据流转环节出现了三个问题:全量没有调度,流程控制增量导致算法得分不具有可比性,会带来一些抖动的业务数据增量在线排序对服务接口造成太大压力(促销失败)。整个链接如上图所示,就是整个链接。算法序列的整个环节依赖于时间约定和数据容灾机制。虚弱的。所以在大促的时候,pre-task延迟做不全,线上内存快满了,full延迟也经常延迟,必须人工处理。也有算法误导排序分数,造成线上混乱,增量恢复时间长。为了解决这个问题,我们首先引入了一个基于Zookeeper的调度系统来驱动整个数据流并支持错误报警。容灾部分的思路是增加排序SOS字段,周期性的基于HBase生成全量快照,快速回滚,修复单算法字段。两种算法的增量分数没有可比性,增量效果特别慢。比如时间1计算出来的产品是90分,时间2是60分,会造成线上排序抖动,主要是算法的两个序列导致了不同的分布整个数据,尤其是大促期间,不同时期的交易数据变化非常快,产品排序的波动非常明显,同一批次的增量数据是正常的,但是看两次就会出错.0点大家都在购物的时候,变动非常频繁,会造成秩序混乱。算法数据出错后,生效时间会变慢。如上图所示,我们的解决方案是将算法和分数分别小量和全量的拖到本地引擎中,在本地引擎中一个一个加载,直接切换,这样每次增量数据的数据算法可以加速有效,让灾难也随之加速。如上图所示,由于变更都是Doc级别的更新,每次字段更新都会调用所有的接口,拼凑出一条完整的数据进行更新,导致业务增量压力特别大。推广期间,增量QPS可达几千到几万,给下游40多个接口带来很大压力。如上图所示,解决这个问题的思路是让引擎,包括数据流,支持字段更新。只拼装变化的字段,不需要拼装完整的数据,需要引擎本身的支持。当时上线的时候,收益非常明显,关键接口的QPS降低了80%以上。平台化(2017.1~现在)是我们现在正在做的事情。面对UPS、广告、商品多引擎系统和广告、搜索多个配送系统被合并来自不同团队,维护成本问题。排序和计算要求变得更加复杂。试图挑战非线性模型和其他方面导致了当前有组织的架构。思路是平台化统一,把重复的系统集成和数据流统一起来。搜索架构探索的经验总结一路走来,整个搜索架构的探索经验就是在发展初期简单快速的支撑在线业务,然后逐步演进满足算法的需求。最后考虑整个应用平台化、统一化的优化思路,提高效率,降低成本。不同阶段有不同的选择。我们首先基于Solr重写。团队和人员包括技术储备有了实力后,我们会直接重写搜索引擎,覆盖算法的线下和线上环节,做系统化建设。我们后续的计划是继续深化新架构的整体平台化,加强算法方面的学习,比如深度学习、在线学习等。如深度学习框架的研究与应用,图像搜索工程系统的构建等。推荐框架探索发展概况蘑菇街的推荐框架已经覆盖了绝大部分的用户行为路径。从使用APP到下单到完成交易,都会有推荐场景。整个推荐架构的发展分为发展初期(2103.11~2015.6),1.0时期:从0到1(2015.6~2016.3),2.0:交付+个性化(2016.3~2016.12),3.0:平台化(2016.2~现在)大舞台。发展初期(2103.11~2015.6),推荐场景不多,需求也比较简单。数据可以离线更新到Redis。当时比较明显的问题是没有专门的推荐系统承载推荐场景,效果跟踪不佳,场景对接,数据导入等效率低下。1.0时期的推荐架构1.0时期:从0到1构建推荐系统(2015.6~2016.3),包括服务层对接场景、实时推荐预测、自写K-V系统存储推荐结果。这里的陷阱之一是让实时预测离线,但实际上实时预测更多的是在线过程。随着时间的推移,场景类型(猜你喜欢,搜索相似,店内)和相似场景(首页,购物车,详情页...)不断增加,需要算法进行排序realtime处理实时点击、追加购买等。还有一些个性化的排序需求,比如店铺、品类、线下偏好等。1.0阶段主要面临三大问题:多类型、多场景:线上不同系统,缺乏统一的对接层,成本高;场景配置:一对一场景算法,代码重复拷贝,维护困难;个性化+实时性:缺乏系统支持;2.0时期推荐的架构如上图所示。2.0时期(2016.3~2016.12)推荐架构主要解决1.0的三大问题,在交付层增加Prism,不同业务场景统一对外连接,Prism动态配置和规则模板。在个性化实时方面,增加了UPS和细排系统。2.0时期推荐架构的交付层配置如上图所示。2.0时期推荐架构的交付层的配置思路是模板化不变的部分,配置可变的部分。该系统提供了用于召回形成、数据完成和格式化的模板。当时,效果很明显。321大促运营位置个性化效果提升20%+,双11大促,场馆个性化楼层提升100%+。大促带来的巨大收益给整个系统带来了非常积极的影响,后续推荐框架面临更多的需求和挑战:增加资源、直播、图片等场景和类型;与美国融合,跨团队、跨地域挑战;工程算法使用一套代码,整个策略的开发调试非常复杂,包括工程部分职责不明确;由于原始的模板化配置,一些简单的场景变得复杂。针对这些问题,我们需要做的是通用化和平台化。整个系统统一推荐方案,自动化整体算法对接核心业务流程,明确算法人员职责分工,提高双方工作效率。3.0推荐架构3.0推荐架构(2016.2~至今)与搜索架构类似,系统间功能更加清晰、统一、平台化,主要是对交付层的改造。3.0时期推荐架构的交付层细节如上图所示。3.0时期推荐架构的交付层的重要概念是场景化。场景应该用于推荐业务,不同的场景会对应不同的策略实现。推荐架构探索总结在推荐架构的早期阶段,和搜索架构一样,需要快速支撑推荐业务,而不需要花费大量精力去搭建一个非常复杂的系统。平台在满足业务和算法需求后,可以提高算法和工程的效率。后续平台化将不断深化,比如算法策略的评估和压力测试工具,全场景的智能监控和告警容灾等。在算法支持方面,是OnlineLearning&ReinforcementLearning,根据算法效果设计新产品。更多详情请观看讲座视频:http://edu.51cto.com/course/course_id-9255.html【原创稿件,合作网站转载请注明原作者和出处为.com】