本文承接执行段的合并(一),继续介绍执行段的合并的剩余的流程,下面先给出执行段的合并的流程图:
图1:
点击查看大图
在上一个流程点作用(apply)删除信息
执行结束后,待合并的段中新增的删除信息目前还存储在内存中,此时需要持久化DocValues信息,即写入到磁盘。
删除信息可以分为下面两类:
在源码中,该流程点有以下的TODO注释:
xxxxxxxxxx
11TODO: we could fix merging to pull the merged DV iterator so we don't have to move these updates to disk first, i.e. just carry them in memory:
也就是说没有必要在这个流程将变更的DocValues信息写入到磁盘,由于由于执行段的合并跟文档的增删改,文档提交(commit、flush)是并发的操作,DocValues还有可能被更新,故在以后的版本,将不需要在这个位置执行该流程,而是跟处理被删除的文档号一样,通过OneMerge存储(仅仅是作者的猜测,至少被删除的文档号是这么做的),OneMerge中包含的信息见文章执行段的合并(一)中的介绍,在后面的流程中会介绍处理被删除的文档号的过程。
至于DocValues信息从内存持久化到磁盘的过程,在以后介绍软删除的文章中会展开,在这篇文章中我们只需要知道,当前流程执行结束后,会生成新的.dvd、.dvm的索引文件。
新段newSegment即待合并的段合并后的目标段(target segment),在合并操作中初始化一个新段的过程有以下五个步骤:
图2:
步骤二之生成SegmentInfo对象:在当前阶段SegmentInfo对象中的变量都是初始化的数据,在后面的流程中会不断的更新SegmentInfo对象中的信息
步骤三之初始化SegmentInfo对象中的Diagnostics:如果是通过flush生成一个新的SegmentInfo对象,那么会将以下的信息初始化Diagnostics:
初始化的Diagnostics包含的字段:
由于是通过merge生成的SegmentInfo对象,所以会额外多两个字段:
Diagnostics在索引文件si中的位置如下图所示,红框标注:
图3:
在介绍该流程之前,我们先讲述下Lucene中两个很重要的类ReadersAndUpdates、ReaderPool。
ReadersAndUpdates用来维护一个段的信息,比如删除信息的更新,段的复用(NRT近实时搜索)等,查询、合并操作都会用到ReadersAndUpdates,它包含的几个重要的变量如下所示:
ReaderPool中包含了一个容器,其定义如下:
xxxxxxxxxx
11private final Map<SegmentCommitInfo,ReadersAndUpdates> readerMap = new HashMap<>();
ReaderPool是IndexWriter的变量,所以ReaderPool的作用是在持有IndexWriter的情况下能通过SegmentCommitInfo找到每一个段的ReadersAndUpdates,故IndexWriter、ReaderPool、ReadersAndUpdates三者的关系如下:
图4:
图4中ReadersAndUpdates的个数即当前索引目录中段的个数。
ReadersAndUpdates在什么时候生成:
图5:
图5的流程图为文档提交之flush(七)中的处理删除信息的流程图。
我们回到流程点更新待合并的段集合OneMerge
,在当前流程点我们需要更新OneMerge中的两个变量,如下所示,OneMerge中包含的信息见文章执行段的合并(一)中的介绍:
详细关于ReaderPool的介绍,可以阅读文章ReaderPool(一)。
该流程会涉及软删除的概念,基于篇幅,将在下一篇文章中展开。
无
点击下载附件