执行段的合并(二)

  本文承接执行段的合并(一),继续介绍执行段的合并的剩余的流程,下面先给出执行段的合并的流程图:

图1:

点击查看大图

DocValues信息写入到磁盘

  在上一个流程点作用(apply)删除信息执行结束后,待合并的段中新增的删除信息目前还存储在内存中,此时需要持久化DocValues信息,即写入到磁盘。

  删除信息可以分为下面两类:

  在源码中,该流程点有以下的TODO注释:

  也就是说没有必要在这个流程将变更的DocValues信息写入到磁盘,由于由于执行段的合并跟文档的增删改,文档提交(commitflush)是并发的操作,DocValues还有可能被更新,故在以后的版本,将不需要在这个位置执行该流程,而是跟处理被删除的文档号一样,通过OneMerge存储(仅仅是作者的猜测,至少被删除的文档号是这么做的),OneMerge中包含的信息见文章执行段的合并(一)中的介绍,在后面的流程中会介绍处理被删除的文档号的过程。

  至于DocValues信息从内存持久化到磁盘的过程,在以后介绍软删除的文章中会展开,在这篇文章中我们只需要知道,当前流程执行结束后,会生成新的.dvd、.dvm的索引文件。

初始化一个新段

  新段newSegment即待合并的段合并后的目标段(target segment),在合并操作中初始化一个新段的过程有以下五个步骤:

图2:

图3:

更新待合并的段集合OneMerge

  在介绍该流程之前,我们先讲述下Lucene中两个很重要的类ReadersAndUpdates、ReaderPool。

ReadersAndUpdates

  ReadersAndUpdates用来维护一个段的信息,比如删除信息的更新,段的复用(NRT近实时搜索)等,查询、合并操作都会用到ReadersAndUpdates,它包含的几个重要的变量如下所示:

ReaderPool

  ReaderPool中包含了一个容器,其定义如下:

  ReaderPool是IndexWriter的变量,所以ReaderPool的作用是在持有IndexWriter的情况下能通过SegmentCommitInfo找到每一个段的ReadersAndUpdates,故IndexWriter、ReaderPool、ReadersAndUpdates三者的关系如下:

图4:

  图4中ReadersAndUpdates的个数即当前索引目录中段的个数。

  ReadersAndUpdates在什么时候生成

图5:

  图5的流程图为文档提交之flush(七)中的处理删除信息的流程图。

  我们回到流程点更新待合并的段集合OneMerge,在当前流程点我们需要更新OneMerge中的两个变量,如下所示,OneMerge中包含的信息见文章执行段的合并(一)中的介绍:

  详细关于ReaderPool的介绍,可以阅读文章ReaderPool(一)

获取SegmentReader的集合MergeReader

  该流程会涉及软删除的概念,基于篇幅,将在下一篇文章中展开。

结语

  

点击下载附件