这是我博客上有关 Apache Lucene 架构的文章的翻译,该架构是关于最著名的搜索索引实现库之一的。 Elasticsearch 和 Solr 都是可扩展搜索解决方案的著名实现,它们在底层使用了这个库。我决方案,在日常工作中我经常遇到这个库。 Apache Lucene 实现了构建搜索引擎的大部分必要功能。从提取单词的规范形式作为标记的标记化过程开始,继续全面实现倒排索引,最后以近乎实时的段复制结束。在该库存在的二十年里,实现的实用功能的数量是巨大的。该图书馆整合了语言学、数学和计算机科学的知识。
倒排索引致力于为电子商务行业创建搜索解
Apache Lucene 实现了倒排索引架构。在实现级别,逻辑索引包含作为文件存储在文件系统中的不可变段的集合。每个段本身就是一个倒排索引。这样的索引是一种字典数据结构,其中术语作为键,帖子作为值。发布是术语出现次数的列表。该词典使用有限状态转换器 (FST [1]) 来查找术语,可以将其视为类似于带间隙的排序列表 [2]。这种排序的导航地图是高效搜索大量文档的基石。 Lucene 的内存效率也非常高。在其他算法中,它使用差异编码算法来压缩帖子中的文档标识符[3]。简而言之,这种压缩背后的想法是对整数列表进行排序并存储它们之间的增量。这也提高了磁盘 I/O 性能。
除了倒排索引之外,Lucene 还可以使用称为 docValues 的面向列的存储来存储文档中的特定字段。它是查询管道中用于分组和排序操作的重要数据结构。它存储特定字段的所有值,按文档标识符排序[4]。这会将检索给定文档集的字段值的操作转变为从磁盘进行的一个顺序读取操作。以前,人们积极使用文档字段的磁盘读取的多次重复操作以及使用 FieldCache 对其进行缓存。
文档标识符和给定文档中
就 Java 类而言,Lucene 包含两个主要用于访问 电话号码库 索引文件的类: IndexWriter 和 IndexReader. JavaDoc Lucene 文档是一个非常好的信息来源。 IndexWriter 类旨在用在应用程序的单个实例中,该实例在内存中累积更新,并在某些条件下更新、提交或将它们保存到文件系统。此外,Writer还。每次提交都会创建新的不可变段文件,将旧文件标记为非活动状态,并删除标记为删除的文档。目前默认的实现是 TieredMergePolicy.
搜索化了过滤器应用阶段
乍一看,实施搜索似乎是一项简单的任务,但在实际实施中,会出现许多细微差别。使用各种分析器将请求文本转换为令牌列表。对于每个标记,都会执行索引搜索。中间结果存储在位集数据结构中。 Lucene 中的接口实现 Bits 可以轻松地对多个标记的搜索结果执行并集/交集操作 [5]。位集简的缓存。当需要过滤或排序时,可以通过将给定文档 ID 集的位集与 docValues 相交来完成。
复制应用了段合并规则来控制段的数量
复制有两种类型:文档复制和段复制。长期 1000 个手机号码 以来,Elasticsearch 和 OpenSearch(Amazon Elasticsearch 的一个分支)仅支持单个文档的复制。 Apache Lucene 添加对近实时段复制的支持已经有一段时间了 [6]。在 Elasticsearch 中实现文档复制需要协调节点收集所有副本对写入操作的响应,这会产生额外的 CPU 负载。
实现分段复制的有趣
创建了开源项目 Nrtsearch [7] 的 Yelp 分享了经验。 Amazon 在 OpenSearch 中采用了分段复制的方法 [8]。它们通过增加网络负载和增加主节 营销进化:从1.0到4.0 点负载来减少CPU负载[9]。现在OpenSearch更进一步:为了减少网络带宽,他们正在实现对网络存储的支持。他们还在尝试点对点段复制[10]。