查看来源

系列文章:

构造 IndexWriter 对象(一)

构造一个 IndexWriter 对象的流程总体分为下面三个部分:

  • 设置索引目录 Directory
  • 设置 IndexWriter 的配置信息 IndexWriterConfig
  • 调用 IndexWriter 的构造函数

  在文章 构造 IndexWriter 对象(一) 中我们讲到了设置 IndexWriter 的配置信息 IndexWriterConfig 中不可配置的内容,接着我们继续介绍可配置的内容。

设置 IndexWriter 的配置信息 IndexWriterConfig

可变配置

  可变配置包含的内容有:MergePolicy、MaxBufferedDocs、RAMBufferSizeMB、MergedSegmentWarmer、UseCompoundFile、CommitOnClose、CheckPendingFlushUpdate。

  可变配置指的是在构造完 IndexWriter 对象后,在运行过程也可以随时调整的配置。

MergePolicy

  MergePolicy 是段的合并策略,它用来描述如何从索引目录中找到满足合并要求的段集合(segment set),在前面的文章了已经介绍了 LogMergePolicyTieredMergePolicy 两种合并策略,这里不赘述。

  MergePolicy 可以通过 IndexWriterConfig.setMergePolicy(MergePolicy mergePolicy) 方法设置,在版本 Lucene7.5.0 中默认值使用 TieredMergePolicy,如果修改了 MergePolicy,那么下一次的段的合并会使用新的合并策略。

MaxBufferedDocs、RAMBufferSizeMB

  RAMBufferSizeMB 描述了索引信息被写入到磁盘前暂时缓存在内存中允许的最大使用内存值,而 MaxBufferedDocs 则是描述了索引信息被写入到磁盘前暂时缓存在内存中允许的文档最大数量, 这里注意的是,MaxBufferedDocs 指的是一个 DWPT 允许添加的最大文档数量,在多线程下,可以同时存在多个 DWPT(DWPT 的概念见 文档的增删改(中)),而 MaxBufferedDocs 并不是所有线程的 DWPT 中添加的文档数量和值

  每次执行文档的增删改后,会调用 FlushPolicy(flush 策略)判断是否需要执行自动 flush(见 文档提交之 flush(一)),在 Lucene7.5.0 版本中,仅提供一个 flush 策略,即 FlushByRamOrCountsPolicy,该策略正是依据 MaxBufferedDocs、RAMBufferSizeMB 来判断是否需要执行自动 flush。

  在 文档的增删改 系列文章中,详细介绍了自动 flush,以及 FlushByRamOrCountsPolicy 的概念,这里不赘述。

  另外在文章中 构造 IndexWriter 对象(一) 中我们说到一个不可配置值,即 RAMPerThreadHardLimitMB,该值被允许设置的值域为 0~2048M,它用来描述每一个 DWPT 允许缓存的最大的索引量。

图 1:

如果你没有看过 文档的增删改 系列文章,那么可以简单的将 DWPT 理解为一个容器,存放每一篇文档对应转化后的索引信息,在多线程下执行文档的添加操作时,每个线程都会持有一个 DWPT,然后将一篇文档的信息转化为索引信息(DocumentIndexData),并添加到 DWPT 中。

  如果每一个 DWPT 中的 DocumentIndexData 的 个数 超过 MaxBufferedDocs 时,那么就会触发自动 flush,将 DWPT 中的索引信息生成为一个段,如图 1 所示,MaxBufferedDocs 影响的是一个 DWPT。

  如果每一个 DWPT 中的所有 DocumentIndexData 的 索引内存占用量 超过 RAMPerThreadHardLimitMB,那么就会触发自动 flush,将 DWPT 中的索引信息生成为一个段,如图 1 所示,RAMPerThreadHardLimitMB 影响的是一个 DWPT。

  如果所有 DWPT(例如图 1 中的三个 DWPT)中的 DocumentIndexData 的 索引内存占用量 超过 RAMBufferSizeMB,那么就会触发自动 flush,将 DWPT 中的索引信息生成为一个段,如图 1 所示,RAMPerThreadHardLimitMB 影响的是所有的 DWPT。

为什么要提供不可配置 RAMPerThreadHardLimitMB

  • 为避免翻译歧义,直接给出源码中的英文注释
Sets the maximum memory consumption per thread triggering a forced flush if
exceeded. A DocumentsWriterPerThread(DWPT) is forcefully flushed once it exceeds
this limit even if the RAMBufferSizeMB has not been exceeded. This is a safety limit to
prevent a DocumentsWriterPerThread from address space exhaustion due to its internal
32 bit signed integer based memory addressing. The given value must be less that 2GB
 (2048MB)
  • 上文中的 forcefully flushed 即自动 flush

  MaxBufferedDocs、RAMBufferSizeMB 分别可以通过 IndexWriterConfig.setMaxBufferedDocs(int maxBufferedDocs)IndexWriterConfig.setRAMBufferSizeMB(double ramBufferSizeMB) 方法设置,其中 MaxBufferedDocs 默认值为-1,表示在 flush 策略中不依据该值,RAMBufferSizeMB 默认值为 16M。

MergedSegmentWarmer

  MergedSegmentWarmer 即预热合并后的新段,它描述的是在执行段的合并期间,提前获得合并后生成的新段的信息,由于段的合并和文档的增删改是并发操作,所以使用该配置可以提高性能,至于为什么能提高性能,以及提高了什么性能可以看文章 执行段的合并(四) 关于 生成IndexReaderWarmer 的介绍。

  MergedSegmentWarmer 可以通过 IndexWriterConfig.setMergedSegmentWarmer(IndexReaderWarmer mergeSegmentWarmer) 方法设置,MergedSegmentWarmer 默认为 null。

UseCompoundFile

  UseCompoundFile 是布尔值,当该值为 true,那么通过 flush、commit 的操作生成索引使用的数据结构都是复合索引文件,即 索引文件.cfs、.cfe

  UseCompoundFile 可以通�