Nautilus的架构,新的Dropbox搜索引擎

简介: Nautilus的架构,新的Dropbox搜索引擎

在过去的几个月里,Dropbox的搜索基础设施工程团队一直在忙于发布一个名为Nautilus的新全文搜索引擎,以取代我们以前的搜索引擎

当涉及到 Dropbox 时,搜索是一个独特的挑战,因为我们的规模庞大,拥有数千亿条内容,并且需要为 5 亿多名注册用户中的每一个提供个性化的搜索体验。它以多种方式进行个性化:不仅每个用户都可以访问一组不同的文档,而且用户在搜索方式上也有不同的偏好和行为。这与网络搜索引擎形成鲜明对比,在网络搜索引擎中,对个性化的关注几乎完全集中在后一方面,而是对每个用户来说基本相同的文档语料库(除了地方之外)。

此外,我们为搜索编制索引的某些内容经常更改。例如,考虑一个用户(或多个用户)处理报表或演示文稿。随着时间的推移,它们将保存多个版本,每个版本都可能更改文档应可检索的搜索词。

更一般地说,我们希望以最有效的方式帮助用户在此特定时刻找到与给定查询最相关的文档。这需要能够在搜索管道的多个阶段利用机器智能,从特定于内容的机器学习(如图像理解系统)到可以更好地对搜索结果进行排名以适应每个用户偏好的学习系统。

Nautilus 团队与我们的机器智能平台合作,扩展了我们的搜索排名和内容理解模型。这些类型的系统需要大量的迭代才能正确,因此能够尝试不同的算法和子系统,并随着时间的推移逐步逐步改进系统是至关重要的。因此,我们在启动鹦鹉螺号项目时为自己设定的主要目标是:

  • 提供一流的性能、可扩展性和可靠性,以应对数据规模
  • 为实现智能文档排名和检索功能奠定基础
  • 构建一个灵活的系统,使我们的工程师能够轻松自定义用于运行实验的文档索引和查询处理管道
  • 而且,与任何管理用户内容的系统一样,我们的搜索系统需要快速,可靠地实现这些目标,并具有强大的保护措施来保护用户数据的隐私

在这篇博客文章中,我们描述了Nautilus系统的架构及其关键特征,详细介绍了我们在设计技术和方法方面所做的选择,并解释了我们如何在系统的各个阶段使用机器学习(ML)。

高级体系结构

鹦鹉螺由两个基本上独立的子系统组成:索引和服务。

索引管道的作用是处理文件和用户活动,从中提取内容和元数据,以及创建搜索索引。然后,服务系统使用此搜索索引返回一组结果以响应用户查询。这些系统共同跨越多个地理位置分散的 Dropbox 数据中心,在一千多台物理主机上运行数以万计的进程。

构建索引的最简单方法是定期循环访问 Dropbox 中的所有文件,将它们添加到索引中,然后允许服务系统应答请求。但是,这样的系统将无法跟上任何接近实时的文档更改,因为我们需要能够做到这一点。因此,我们遵循一种混合方法,这种方法对于大规模的搜索系统来说相当普遍:

  • 我们会定期生成搜索索引的“离线”构建(平均每 3 天一次)
  • 当用户与文件和彼此交互(例如编辑文件或与其他用户共享文件)时,我们会生成“索引突变”,然后将其近乎实时地应用于实时索引和持久性文档存储(大约几秒钟)。

我们将讨论的系统的其他一些关键部分是如何索引不同类型的内容,包括使用ML来理解文档,以及如何使用基于ML的排名服务对检索到的搜索结果(包括来自其他搜索索引)进行排名。

数据分片

在我们讨论鹦鹉螺号中的特定子系统之前,让我们简要讨论一下如何达到所需的规模水平。对于数千亿条内容,我们需要对大量数据进行索引。我们将这些数据拆分或“分片”到多台计算机上。为此,我们需要决定如何对文件进行分片,以便快速完成每个用户的搜索请求,同时在我们的机器之间相对均匀地平衡负载。

在 Dropbox,我们已经有这样一个用于对文件进行分组的架构,称为“命名空间”,可以将其视为一个或多个用户有权访问的文件夹。这种方法的好处之一是,它允许我们只看到他们有权访问的文件的搜索结果,这就是我们允许共享文件夹的方式。例如:文件夹成为共享者和共享收件人都有权访问的新命名空间。Dropbox 用户可以访问的文件集完全由她被授予访问权限的一组基础命名空间定义。给定命名空间的上述属性,当用户搜索术语时,我们需要搜索他们有权访问的所有命名空间,并合并所有匹配的结果。这也意味着,通过将命名空间传递到搜索系统,我们只搜索查询用户可以在执行搜索时访问的内容。

我们将许多命名空间分组到一个“分区”中,该“分区”是我们存储、索引和提供数据的逻辑单元。我们使用一种分区方案,允许我们在将来随着需求的变化轻松地对命名空间进行重新分区。

索引

文档提取和理解

用户希望搜索的内容有哪些?当然,每个文档都有内容,即文件中的文本。但还有许多其他类型的数据和元数据是相关的。

我们设计了 Nautilus 来灵活地处理所有这些以及更多内容,通过定义一组“提取器”,每个“提取器”从输入文件中提取某种输出并写入我们“文档存储”中的一列。底层技术具有额外的自定义构建层,可提供访问控制和数据加密。它每个文件包含一行,每列包含特定提取程序的输出。此架构的一个显著优点是,我们可以轻松地并行更新一行上的多个列,而不必担心一个提取器的更改会干扰其他提取器的更改。

对于大多数文档,我们依靠Apache Tika将原始文档转换为规范的HTML表示形式,然后对其进行解析以提取“标记”(即单词)及其“属性”(即格式,位置等)的列表。

提取令牌后,我们可以使用“Doc Understanding”管道以各种方式增强数据,该管道非常适合尝试提取可选元数据和信号。作为输入,它采用从文档本身提取的数据,并输出一组附加数据,我们称之为“注释”。称为“注释器”的可插拔模块负责生成注释。简单注释器的一个例子是词干分解模块,它基于原始标记生成词干标记。另一个例子是将令牌转换为嵌入,以实现更灵活的搜索。

脱机生成

文档存储包含整个搜索语料库,但它不太适合运行搜索。这是因为它存储按文档 ID 映射的提取内容。对于搜索,我们需要一个倒置的 index:从搜索词到文档列表的映射。脱机生成系统负责定期从文档存储区重新生成此搜索索引。它在我们的文档存储上运行相当于MapReduce作业的作业,以便建立一个可以非常快速查询的搜索索引。每个分区最终都有一组存储在“索引存储”中的索引文件。

通过将文档提取过程与索引过程分开,我们为实验提供了很大的灵活性:

  • 修改索引本身的内部格式,包括试验可提高检索性能或降低存储成本的新索引格式的能力。
  • 将新的文档注释器应用于整个语料库。一旦注释器在应用于即时索引管道中流动的新文档流时显示出优势,只需将其添加到脱机生成管道中,即可在几天内将其应用于整个文档语料库。与必须运行大型回填脚本来更新文档存储中的数据文档集相比,这提高了试验速度。
  • 改进用于筛选已编制索引的数据的试探法。毫不奇怪,在处理数千亿个内容时,我们必须保护系统免受可能导致准确性或性能下降的边缘情况的影响,例如,一些非常大的文档或文档被错误地解析并生成乱码令牌。我们有几个用于从索引中筛选出此类文档的试探法,并且随着时间的推移,我们可以轻松地更新这些试探法,而不必每次都重新处理源文档。
  • 能够缓解由新实验引起的不可预见的问题。如果索引过程中出现一些错误,我们可以简单地回滚到索引的以前版本。这种保护措施转化为在试验时对风险和迭代速度的更高容忍度。

 

服务

服务系统由前端组成,前端接受并转发用户搜索查询;一个检索引擎,它为每个查询检索大量匹配文档;以及一个名为Octopus的排名系统,该系统使用机器学习对多个后端的结果进行排名。我们将重点介绍后两者,因为前端是一组相当简单的 API,我们所有的客户端(Web、桌面和移动)都使用。

检索引擎

检索引擎是一个分布式系统,它提取与搜索查询匹配的文档。该引擎针对性能和高召回率进行了优化 - 它的目标是在给定的时间预算中返回尽可能多的候选项。这些结果将按我们的搜索编排层八达通进行排名,以达到高精度,即确保最相关的结果在列表中名列前茅。检索引擎分为一组“叶子”和一个“根”:

  • 主要负责将传入的查询扇出到保存数据的叶子集,然后接收和合并叶子的结果,然后再将它们返回给八达通。
  • 根还包括一个“查询理解”管道,这与我们上面讨论的文档理解管道非常相似。这样做的目的是转换或批注查询以改善检索结果。
  • 每个处理一组命名空间的实际文档查找。它管理倒排转发的文档索引。通过从脱机生成过程下载生成来定期为索引设定种子,然后通过应用从 Kafka 队列消耗的突变来不断更新索引。

搜索业务流程协调程序

我们的搜索编排层称为八达通。八达通收到用户的查询后,首先要调用 Dropbox 的访问控制服务,以确定用户具有读取访问权限的确切命名空间集。此集定义将由下游检索引擎执行的查询的“范围”,确保仅搜索用户可访问的内容。

除了从 Nautilus 检索引擎获取结果之外,我们还必须执行几项操作,然后才能将最终的结果集返回给用户:

  • 联邦:除了我们的主文档存储和检索引擎(如上所述)之外,我们还有一些单独的辅助后端,需要查询特定类型的内容。这方面的一个例子是Dropbox Paper文档,它目前在单独的堆栈上运行。八达通提供向多个后端搜索引擎发送搜索查询和合并结果的灵活性。
  • 影子引擎:提供来自多个后端的结果的能力对于测试主检索引擎后端的更新也非常有用。在验证阶段,我们可以将搜索查询发送到生产系统和正在测试的新系统。这通常称为“影子”流量。仅将生产系统的结果返回给用户,但会记录来自两个系统的数据以供进一步分析,例如比较搜索结果或测量性能差异。
  • 排名:八达通从搜寻后端收集候选文件名单后,会根据需要提取额外的讯号及元数据,然后把该资料发送至个别的排名服务,而该分级服务则计算分数,以选择返回给用户的最终结果名单。
  • 访问控制 (ACL) 检查:除了将搜索限制在查询范围中定义的命名空间集的检索引擎外,在八达通层增加了一层额外的保护,方法是在返回之前仔细检查检索引擎返回的每个结果是否可以由查询用户访问。

请注意,所有这些步骤都必须非常快地进行 - 我们的目标是第95百分位搜索的预算为500毫秒(即,只有5%的搜索应该花费超过500毫秒)。在以后的博客文章中,我们将描述我们如何实现这一目标。

机器学习驱动的排名

如前所述,我们调整了检索引擎以返回大量匹配的文档,而不必太担心每个文档与用户的相关性。排名步骤是我们关注范围的另一端:选择用户现在最有可能想要的文档。(在技术术语中,检索引擎针对召回进行调整,而排名器针对精度进行调整。

排名引擎由 ML 模型提供支持,该模型根据各种信号为每个文档输出分数。一些信号测量文档与查询的相关性(例如,BM25),而另一些信号则测量文档在当前时刻与用户的相关性(例如,用户一直在与谁交互,或者用户一直在处理哪些类型的文件)。

该模型使用来自我们前端的匿名“点击”数据进行训练,其中不包括任何个人身份数据。给定过去的搜索以及点击的结果,我们可以学习相关的一般模式。此外,该模型经常重新训练或更新,随着时间的推移适应和学习一般用户的行为。

使用基于ML的解决方案进行排名的主要优点是,我们可以使用大量信号,以及自动处理新信号。例如,您可以想象为我们提供的每种类型的信号手动定义“重要性”,例如用户最近与哪些文档进行了交互,或者文档包含搜索词的次数。如果您只有少量信号,这可能是可行的,但是当您添加数十个或数百个甚至数千个信号时,这变得不可能以最佳方式完成。这正是ML的亮点:它可以自动学习用于对文档进行排名的正确“重要性权重”集,以便向用户显示最相关的“重要性权重”。例如,通过实验,我们确定与新鲜度相关的信号对更相关的结果有显着贡献。

结论

经过一段时间的资格认证,Nautilus在阴影模式下运行,它目前是Dropbox的主要搜索引擎。我们已经看到对新内容和更新内容编制索引的时间有了重大改进,并且还有更多其他改进。

现在我们已经有了坚实的基础,我们的团队正忙于在Nautilus平台之上进行构建,以添加新功能并提高搜索质量。我们正在探索新功能,例如在嵌入空间中使用基于距离的检索来增强现有的发布列表检索算法;解锁搜索图像,视频和音频文件;使用额外的用户活动信号改善个性化;以及更多。在本文的第二部分中,了解我们如何验证 Nautilus 的性能和可靠性。

Nautilus 是 Dropbox 工程师处理的大型项目类型的典型例子,这些项目涉及数据检索和机器学习

目录
相关文章
|
搜索推荐
这就是搜索引擎读书笔记-day1-搜索引擎技术架构
这是我看搜索引擎的第一天,希望通过记录督促自己学习
这就是搜索引擎读书笔记-day1-搜索引擎技术架构
|
SQL 机器学习/深度学习 监控
搜索引擎新架构:与SQL不得不说的故事
本话题将围绕阿里巴巴搜索引擎HA3架构,和大家详细阐述搜索引擎在面对架构深度学习和数据规模的挑战时,如何以数据库SQL的执行方式来应对解决。
15626 0
搜索引擎新架构:与SQL不得不说的故事
|
数据采集 搜索推荐 Python
24、Python快速开发分布式搜索引擎Scrapy精讲—爬虫和反爬的对抗过程以及策略—scrapy架构源码分析图
【百度云搜索:http://www.lqkweb.com】 【搜网盘:http://www.swpan.cn】 1、基本概念 2、反爬虫的目的 3、爬虫和反爬的对抗过程以及策略 scrapy架构源码分析图
5991 0
突破Java面试(14)-分布式搜索引擎的架构
在搜索这块,曾经lucene 是最流行的搜索库. 几年前业内一般都问,你了解 lucene 吗?你知道倒排索引的原理吗? 但现在不问了,因为现在项目基本都是采用基于 lucene 的分布式搜索引擎—— ElasticSearch. 现在分布式搜索基本已经成为互联网系统的标配,其中尤为流行的就是 ES,前几年一般用 solr。
2925 0
|
搜索推荐 Apache 数据库
推荐[搜索引擎架构]的几篇文章
1.基于Sphinx+MySQL的千万级数据全文检索(搜索引擎)架构设计 http://blog.s135.com/post/360/ 2.百度、新浪、Mixi、Apache社区赞助的开源key-value分布式存储系统 http://blog.
1426 0
|
4天前
|
运维 负载均衡 Cloud Native
云原生架构技术之云原生微服务
微服务模式将后端单体应用拆分为松耦合的多个子应用,每个子应用负责一组子功能。这些子应用称为“微服务”,多个“微服务”共同形成了一个物理独立但逻辑完整的分布式微服务体系。这些微服务相对独立,通过解耦研发、测试与部署流程,提高整体迭代效率。此外,微服务模式通过分布式架构将应用水平扩展和冗余部署,从根本上解决了单体应用在拓展性和稳定性上存在的先天架构缺陷。但也要注意到微服务模型也面临着分布式系统的典型挑战:如何高效调用远程方法、如何实现可靠的系统容量预估、如何建立负载均衡体系、如何面向松耦合系统进行集成测试、如何面向大规模复杂关联应用的部署与运维。
22 4
|
5天前
|
敏捷开发 负载均衡 监控
探索微服务架构下的API网关设计与实践
【5月更文挑战第31天】本文将深入剖析微服务架构中的关键组件——API网关,探讨其设计理念、核心功能以及在实际项目中的应用。我们将从API网关的基本概念出发,逐步展开对其路由、负载均衡、认证授权、监控日志等方面的详细讨论,并结合实际案例,分析如何高效地实现和管理一个稳定的API网关。
|
5天前
|
缓存 监控 安全
微服务架构下的API网关设计与实践
【5月更文挑战第31天】本文深入探讨了在微服务架构中,API网关的核心作用与设计策略。通过分析网关的职责、选型标准及实现细节,文章为读者提供了一套完整的API网关解决方案。同时,结合具体案例,展示了如何在实际应用中有效部署和优化API网关,确保系统的高可用性和可扩展性。
|
5天前
|
API 开发者 微服务
探索后端开发中的微服务架构
【5月更文挑战第31天】在数字化浪潮中,微服务架构如星辰般熠熠生辉,为后端开发领域带来革命性的创新。本文将深入探讨微服务架构的精髓,从其定义、核心优势到实际应用,展现这一技术如何在复杂业务场景下提供灵活、高效的解决方案。我们将一同见证微服务如何助力企业快速响应市场变化,实现技术的可持续发展。
|
5天前
|
运维 监控 Docker
构建高效微服务架构:从理论到实践构建高效自动化运维体系:Ansible与Docker的完美融合
【5月更文挑战第31天】 在当今软件开发的世界中,微服务架构已经成为了实现可伸缩、灵活且容错的系统的关键策略。本文将深入探讨如何从零开始构建一个高效的微服务系统,涵盖从概念理解、设计原则到具体实施步骤。我们将重点讨论微服务设计的最佳实践、常用的技术栈选择、以及如何克服常见的挑战,包括服务划分、数据一致性、服务发现和网络通信等。通过实际案例分析,本文旨在为开发者提供一套实用的指南,帮助他们构建出既健壮又易于维护的微服务系统。