如今,我们几乎在每个网站上都看到一个搜索栏。搜索栏使我们能够快速找到我们需要的内容。
让我们举个例子。想象一下,如果YouTube没有提供搜索栏,我们如何在数百万个视频中找到特定的视频,这些视频多年来都已上传到YouTube?用户仅通过滚动浏览很难找到他们想要的内容。
在每个搜索栏背后,都有一个搜索系统。
图1.0:倒排索引
“映射”列中的每个条目都包括三个列表:
对于提取的每个词语,我们要么在倒排索引中添加新行,要么在该词语已经在倒排索引中有条目的情况下更新现有条目。同样,在删除文档时,我们需要处理,找到已删除文档词汇在倒排索引中的条目,然后相应地更新倒排索引。
在添加文档或运行搜索查询时,需要将倒排索引加载到主内存中。为了效率,必须将倒排索引的大部分内容适应于机器的RAM中。
这意味着我们必须将大量数据加载到RAM中。不是增加单台机器的资源来索引十亿页,而是要转向分布式系统,利用并行化的力量。
图2.0:分布式搜索系统的高级设计
为了实现成本效益,我们在索引中使用了众多小节点。这个过程要求我们对输入数据(文档)进行分区或拆分。
图3.0:在多个普通机器集群中以并行方式进行分布式索引和搜索
索引:
搜索:
我们为生成分配分区的索引节点创建副本。
通常,三个副本足够。三个副本意味着三个节点托管相同的分区并生成索引。三个节点中的一个成为主节点,而其他两个是副本。同一分区将转发到所有三个副本。我们假设每个副本都会独立计算索引,这会导致资源的低效使用。与在副本上重新计算索引不同,我们只在主节点上计算倒排索引。接下来,我们将倒排索引(二进制文件)传输到副本。这种方法的主要好处是避免了在副本上使用重复的CPU和内存来进行索引。
图4.0:由索引节点生成的索引存储在分布式存储中,参与搜索的节点从分布式存储中读取索引以为用户的查询生成结果
索引和搜索之间有很强的分离,而没有索引延迟的负面影响。由于这种分离,索引不会影响搜索可扩展性,反之亦然。此外,与在副本上重新计算索引不同,我们只需复制索引文件。
在硬件故障的情况下,会添加新的搜索器或索引器机器,并从分布式存储中检索数据的副本。
数据在分布式存储中跨多个区域进行复制,使索引和搜索的跨区域部署更加容易。因此,如果一个地方发生故障,我们可以在另一个集群中处理请求。
索引是离线执行的,不在用户的关键路径上。我们不需要同步复制索引操作。无需在将新索引复制到响应搜索查询之前等待。这使得搜索对用户可用。
分区是搜索系统扩展的重要组成部分。当增加分区的数量并向索引和搜索集群添加更多节点时,可以在数据索引和查询方面实现扩展。
索引和搜索过程之间的强分离有助于索引和搜索独立和动态地扩展。
我们利用了多个节点,每个节点在较小的倒排索引上并行执行搜索查询。然后,将每个搜索节点的结果合并并返回给用户。