搜索的演变-如何通过三次点击购买钢琴

以前,在Avito上,您可以使用关键字过滤或类别树导航找到合适的产品。 这种方法虽然看起来很熟悉,但并不总是很方便-为了找到产品或服务,必须进行大量的点击。 一年多以前,我们已经获得了相关性,因此搜索变得更加出色,现在即使在主页上也可以更轻松,更方便地找到产品或服务。 通过这种创新,不合适的,坦率的“垃圾”商品不再成为问题。 这只是使您的搜索更好的步骤之一。 我们正在逐步改变基础架构,这使我们能够更深入地研究搜索质量,更快地改善搜索质量并推出新功能,从而使Avito的买卖双方受益。


在文章中,我将告诉您在Avito上进行搜索的方式是如何改变的:我们从哪里开始以及现在如何朝着改善用户生活的方向前进,我将在产品及其填充方面(技术部分)分享我们的创新。 这里不会有铁杆肉,但我希望你喜欢。



一些介绍性注释:Avito是俄罗斯最受欢迎的广告服务。 我们每天有超过45万个广告,每月的独立访问者人数达到3500万,每天的搜索量超过1.4亿。


之前的典型搜索场景


让我们看一个简单的示例,说明一年多以前搜索是如何工作的。 假设您需要一架钢琴(嗯,为什么不呢?)。 我们进入主页,输入“ piano”。



在引渡中,您很可能会收到搬家公司,钢琴运输服务或类似物品,但不会收到乐器。



发生这种情况是因为我们将按放置日期进行排序-并且这些服务放置频率最高。



要观看钢琴,您需要指定类别。 我们单击标题“爱好与休闲”,在类别树中依次选择“乐器”,然后是“键盘乐器”。




而且只有在那之后,我们才能看到我们想要的钢琴。



事实证明,要找到所需的广告,有以下几种选择:


  • 通过关键字搜索时,对类别进行细化,
  • 按新鲜度和价格排序
  • 过滤器
  • 仅按名称搜索。

相关性改变了什么


由于相关性,根本不适合的广告已不再包含在发行中。 现在,如果您要从主页上查找钢琴,则很可能看不到帮助您运输钢琴的装载机服务,但您会立即看到想要的乐器。 同时,添加了新的排序-“默认”。 它由两个指标组成:与文本查询相关的广告和新鲜度。



在顶部,您会看到最相关的内容。



在Avito上,您可以额外付费才能刊登广告。 随着相关性的引入,收费提升工作更加有效。 首先,如果您的广告与文字查询相关,则它们将起作用。


相关性的引入并不意味着我们完全放弃了到类别树的过渡。 在大多数情况下,从首页搜索时,我们减少了对所需广告的点击次数。 如果您仍然需要运输服务,尽管您只是在搜索中输入了“钢琴”,但要仔细检查类别树,您会发现这些广告。 搜索也开始更有效地进行,并且在“个人物品”和“家用电器”等类别中进行搜索。


如何通过三点击找到合适的产品


不仅由于搜索结果的质量,搜索对用户而言变得更加方便。 还有其他方法可以改善它。 其中之一是转发到类别。 例如,我们正在寻找Lamborghini Gayardo(是的,您喜欢弹钢琴并且想骑Lamborghini)。 要进入特定型号汽车的类别,您需要额外点击两次。 具有相关性,很可能会得到您想要的。



但是还有另一种方法可以立即将您带入汽车。 发行将变窄,将在过滤器中选择合适的汽车,您实际上会在发行中收到汽车。




另一种方法是扩展标签。 例如,当您输入单词“夹克”时,您将获得提示。



上面的屏幕截图显示了提示:夹克的类型-女,男,女孩,男孩。 如果单击“对于女孩”,您将立即进入选择适当过滤器的类别。 一组附加的扩展标签也将出现在这里:冬装,皮革,新标签等。 如果您手动将类别树放入所需的产品,则需要执行更多操作。



搜索和过滤条件有什么区别


当我在RIT ++上发言时,听众有一个问题:文本搜索和过滤器之间有什么区别? 一切都很简单。 您还可以通过类别树下的内容找到无需文字请求的所需广告。 在这种情况下,搜索仍将找到商品和服务,而不是通过给定的文本,而是通过从所选类别的相应过滤器传递的参数集。


每个类别都有自己的一组过滤器。 例如,在“汽车”类别中-一些过滤器,在“个人物品”类别中-其他过滤器。 也就是说,过滤器严格地与类别相关联。


两分钟内发布公告


对于卖家来说,他们提交广告时感到了一项重要的创新。 如果您的广告不包含任何“禁止”或不是重复的(通常是好的广告),您几乎会立即在发行中看到它。 实际上,这种延迟大约持续两分钟,但是在极少数情况下,可以延长到30分钟。 以前,广告只会在半小时后才会出现在网站上。


Avito助手


Avito Helper是Chrome的扩展程序,可在Avito上的第三方网站上显示类似产品的价格。 在扩展程序中,您可以将许多在线商店的价格与Avito的价格进行比较,或者直接在我们的服务中搜索必要的商品和服务,而无需直接访问网站或应用程序。 我们能够实施“助手”,这要归功于新的基础架构变更。



建筑学


锯整体


Avito在PHP中独树一帜。 一年前,在Avito中可用的所有搜索功能都在这个整体中。 在整体搜索中使用了四个平台:Android,iOS,浏览器中的移动版本和桌面。 为了提供输出,在此代码内的Sphinx中生成了相应的SQL查询,正在进行处理,并以JSON或HTML格式发送输出。 然后用户看到了他们想要的东西。



我们现在拥有的


如果实现新功能,则很难与该整体集成。 因此,我们决定开发一种搜索服务,称为“搜索”。 现在,整体程序转到该搜索服务,该服务转到Sphinx。



创建搜索服务的原因


在开发服务时,您始终需要了解为什么要这样做。 第一个明显的优点是取消了底层逻辑。 在我们的案例中,这隐藏了用于处理SphinxQL查询的厨房。 此外,我们可以更轻松地向第三方系统提供搜索功能。


异步查询执行。 这种优势非常明显,根据实现的不同,可以获得一个或另一个成功。 我们的服务是在Golang上实现的,并且具有可以并行化的功能-Sphinx中有三个请求,因此效果很好。


快速部署。 我们已经确定了一个单独的功能,它具有较少的代码,额外的测试(整体式程序具有很多测试,而不仅仅是搜索功能),并且更容易推出。 最重要的是,由于成功实现了此服务的方法,我们能够减少有趣的事情并实现高级排名算法-进行我们无法在整体中完成的相当复杂的处理。 这为我们尝试搜索质量提供了很好的基础。


另外,我们现在有机会从Sphinx切换到Elastic,因为现在隐藏了底层逻辑。


该图已经显示了存在整体,服务“ Searched”和第三方服务“ Avito Assistant”的情况。



搜索服务如何工作?


它具有一组聚合器。 每个聚合器执行与发行处理有关的特定业务逻辑。 他可以以某种方式解决这个问题。


该请求到达调度程序。 调度程序根据查询条件根据其参数选择聚合器(或者如果在请求本身中指定了所需的聚合器)。 聚合器转到Sphinx。 收到Sphinx的响应后,它会生成输出并将答案提供给客户端。



在这种情况下,请求来自外部,而不是来自我们搜索服务所在的云。 但是还有另一个选择是可能的:云中的其他一些服务(例如Avito Assistant)转向了搜索服务。 该请求已经发送给另一个聚合器-还有另一个业务逻辑。 运作方式如下:



聚合器上异步查询执行的工作方式


聚合器包含几个配置文件。 简而言之,配置文件是一个实体,您可以在其中获得某种类型或特定方式的公告。 例如,可以用一个类比来解释:在Avito上有“ Premium”,“ VIP”和常规广告。 聚合器从调度程序接收请求,而并行请求则针对聚合器中已知的一组概要文件执行。 该配置文件内部有一个驱动程序,可物理访问基础级别(在本例中为Sphinx),但它可以是任何其他数据源



聚合器可以简单地向调度程序提供对概要文件的查询结果,并且它还可以执行更复杂的操作,例如,使用一种或另一种算法混合这些结果。



搜索索引存储


由于我们在架构中使用Kubernetes,因此在RIT ++上有人问我有关存储搜索索引的问题-它存储在Kubernetes中吗? 不,我们让Sphinx生活在物理机器上。 在Kubernetes,我们正在部署一个处理搜索逻辑的搜索服务。 云还包含用于在其上运行测试的开发环境的样本搜索索引,但是不建议在其中放置战斗索引,因为在Kubernetes中运行的服务首先是无状态服务。


搜索服务负荷


现在,这项服务正在战斗中,它可以满足100%的负载,但有一些例外。 他保持的负载约为200 krpm。 延迟:中位数-最高17 ms,95%-最高120 ms,99%-最高320 ms。




全面搜索服务


搜索服务是用Golang编写的,并已部署到Kubernetes,聚合器与多个配置文件异步工作。 该配置文件与指定的驱动程序一起使用,该驱动程序访问指定的数据源,例如Sphinx。 目前,我们的服务所服务的请求数量高达200 krpm。 延迟:中位数-最高17 ms,95%-最高120 ms,99%-最高320 ms。


在工作系统中实施服务


双重功能的问题非常明显,我们必须支持必须执行相同任务的两个代码库。 我们需要一个后备。 我们称其为“稻草”-我们记得“稻草”。 另外,我们需要流量控制,希望通过仪表板来实现快速控制。


“稻草”如何


搜索查询进入“秸秆”,该秸秆在整体内部工作,可以进一步调用新搜索还是旧搜索。 她打电话给新的搜索,他完成了,如果成功,我们只是从新的搜索中得到结果。



在某些情况下,对搜索服务的查询失败:例如,直到在搜索服务内部实现某种功能为止。 然后我们必须保证这样的请求-“稻草”将在旧搜索中执行它。 来自整体的旧搜索将转向Sphinx,答案将交给客户。 客户不会有任何感觉。



一个相当可靠的方案,并且观察实践中发生的事情总是很有趣。 Avito建筑部正在不断改进我们的云,进行调整,使其更加可靠和高效。 在某个阶段,存在一些问题,当以足够高的强度维修其中一个节点时,错误就来自整体(每秒100个错误)。



同时,服务延迟急剧增加-在下图中可以看到峰值。



“稻草”解决了这种情况,导致的HTTP错误处于同一级别-整个Avito的错误单位。 我们的访客没有发现任何东西。



实验自动化


我们希望搜索能够快速发展,并且向其中推出新功能更加容易。 为此,需要适当的基础架构。 我们已经配置了A / B测试的自动化。 使用仪表板,我们可以开始新的实验,根据添加的创新来配置它们,并因此在不滚动整体的情况下运行实验。


在初始状态下,当没有一个实验启动时,所有访问者都会看到通常的搜索功能。



在典型的实验中,用户分为几组。 对照组-具有访问者常用的功能。 有多个测试组-具有创新性。 当需要创建新实验时,在搜索服务中,我们实现了新的搜索功能(添加了新的聚合器),并通过仪表板为实验设置了必要的组,并将其与新的聚合器链接。


在分析实验时,我们将对照组和测试组中访问者的行为进行比较,并在此基础上得出关于实验成功的结论。



假设我们开发了一个新的排名公式。 要对她进行实验,我们需要做什么?


  1. 在搜索服务中,推出适当的聚合器(将其命名为“聚合器2”)。
  2. 通过仪表板创建一个实验,并将该实验中的组之一与此聚合器连接。
  3. 现在,如果查询进入属于测试组的搜索,它将转到“聚合器2”上的搜索服务。

我们可以继续创建新的实验,并将其测试组与新的聚合器相关联。


整体搜索基础架构


这里有一个Sphinx 3服务器集群,可容纳13 krps的SphinxQL查询,并且拥有超过4500万个活动广告。


Sphinx 3.0稳定且对其性能感到满意。 顺便说一下,二进制文件在公共领域 。 此外,借助Avito,Sphinx 3中还记录了新功能,例如,向量的标量积的运算,并修复了已发现的错误。


我们使用服务架构。 我们有搜索服务“ Iskalo”和服务“ Avito Assistant”。 部分功能仍保留在整体中,但我们将继续对其进行切割。


结论


在过去的一年中,已经收到了高级搜索功能开发系统。 我们有机会进行快速灵活的实验。 现在,对用户的搜索已变得更加方便,快捷和更好,有助于解决他们的问题。


接下来是什么


此外,我们将继续从整体中删除剩下的内容:渲染,过滤器。 我们将努力提高搜索质量,继续取悦我们的访客。 希望你也一样。


如果您对我们的搜索工作有疑问,我们想了解更多技术细节,请在评论中写下。 我会很乐意回答。 顺便说一句,最近,安德烈·德罗兹多夫(Andrey Drozdov)在Highload ++ 2018上发表了一篇关于搜索结果多标准优化的报告 ,这是他的演讲

Source: https://habr.com/ru/post/zh-CN429076/


All Articles