原文链接:
http://java.dzone.com/news/merge-policy-internals-solr?mz=33057-solr_lucene
solr(or lucene)内部的合并策略是怎样的呢?
选择哪些段(segment)需要被合并,是基于名为
MergePolicy的抽象类决定的。这个类创建了一个合并规则类
MergeSpecification:由
OneMerge对象组成的一个列表集合。其中的每一个代表了一个单独的合并操作;被指定的所有段都将被合并为一个新的段。
在索引改变之后,
IndexWriter会调用
MergePolicy来获取一个
MergeSpecification;然后开始调用
MergeScheduler,该类负责合并任务的执行。
MergeScheduler主要有两个实现类:
ConcurrentMergeScheduler为并行合并的线程类(多线程),
SerialMergeScheduler则会将所有的合并操作在当前线程进行(单线程)。当合并的时间到了,
IndexWriter会将合并的任务交给
SegmentMerger来做。
所以,如果想了解什么时候段会被合并、为什么有些段被合并了而有些没有、或者起来类似的一些问题,我们都应该了解一下
MergePolicy。
MergePolicy有很多的实现,我们来看一下它的默认实现类
LogByteSizeMergePolicy。
MergePolicy定义了三个抽象方法来构造
MergeSpecification:
1. findMerges() 将会在索引被改变时被调用
2. findMergesForOptimize() 在optimize操作时被调用
3. findMergesToExpungeDeletes() 在删除操作时被调用
Step by step
下面先对合并策略作一个简短的概念性描述,请看下图:
1. 将段按name排序
2. 将已存在的段分组(level),每个组(level)都是连续段的集合
3. 对于每个组,确定将要被合并的段
Parameters
下面来说明一下在合并索引时需要用到的一些参数:
1. mergeFactor: 这个参数有多种含义,比如有多少段将被合并为新段;每个组的最大段数和每个段的跨度,可以在solrconfig.xml里设置
2. minMergeSize:小于该值的所有段将会被归于一个组中,固定值
3. maxMergeSize:大于该值的所有段将不会被合并,固定值
4. maxMergeDocs:所有文档数大于该值的段将不会被合并,以上参数均在solrconfig.xml中定义
Constructing the levels
让我们看一下组(level)是如何被构造的。为确定第一个组,算法会查询最大合并段大小,我们叫它levelMaxSize。如果这个值小于minMergeSize,那么所有的段都会被归为一个组。否则,levelMaxSize的值将为:
这个算法的大致含义为:levelMaxSize的值大约为levelMaxSize除以mergeFactor的0.75次方(如果1被使用则替代0.75),但是如果算出的值小于minMergeSize,则用minMergeSize代替。
通过这个计算,算法将会选择哪些段属于当前的组。首先,它讲找一个大于或等于levelMinSize的段,如果其他旧的段都比它小,则被归为一个组。下一个组也会使用相同的方式,但是会找比上一个段更新的段作为比较段。
下面举个例子,设mergeFactor=10 and minMergeSize=1.6MiB.
首先取第一个段200M,得出levelMaxSize为36M,那么只有I比它大;分为一组,继续选择8.9M得出levelMaxSize为1.6M,计算后与6.5M分为一组……
但是,如果你不了解算法本身,它会构造出你无法预料的组。举个例子,下面的表中,依然设置mergeFactor=10 and minMergeSize=1.6MiB.
Segment Size
a 200 MiB
l 88 MiB
m 8.9 MiB
n 6.5 MiB
o 1.4 MiB
p 842 KiB
q 842 KiB
r 842 KiB
s 842 KiB
t 842 KiB
u 842 KiB
v 842 KiB
w 842 KiB
x 160 MiB
会有多少组呢?来看一下:最大的段大小为200M,则levelMinSize为36M;最新的比levelMinSize 大的段是x,所以第一个组包括x并且所有的段都比它旧。那么,这将只有一个组!
Choosing which segments to merge
在定义完组之后,
MergePolicy将会选择哪些段会被合并:单独的分析每个组,如果一个组小于mergeFactor 个段,那么该组会被忽略(不合并)。否则,所有在该组中的段都将被合并为一个新的段;如果组中有大于maxMergeFactor或maxMergeDocs的段,则该段被忽略。
回到第2个例子中,当只有一组段需要合并时,合并结果为:
Segment Size
u 842 KiB
v 842 KiB
w 842 KiB
x 160 MiB
y 311 MiB
minMergeSize and maxMergeSize
这个说说这两个参数。目前这两个值在lucene中是硬编码的,他们的值为:
minMergeSize:1.6M 所有比1.6M小的段都将被归为1组
maxMergeSize:2G 所有大于2G的段都不会再被合并
Conclusion
其实这个算法并不复杂,如果想知道在你的索引添加多个文档时发生了什么,了解其内部机制是有必要的。同时,了解合并策略是如何工作的,更能帮助你设定一些参数的值(如mergeFactor和maxMergeDocs)。
- 大小: 23.9 KB
- 大小: 1.3 KB
- 大小: 18.3 KB
分享到:
相关推荐
Lucene 删除 合并索引,可以指定几个索引文件合并成一个索引文件。自己写的,有很多不足之处请多指教
基于Lucene的搜索策略研究
lucene实例lucene实例lucene实例lucene实例lucene实例lucene实例lucene实例lucene实例lucene实例
针对中文检索的Lucene改进策略 为了提高基于Lucene中文检索系统的检索精度和效率,通过分析Lucene的结构,在系统中加入了中文分词模块和索引 文档预处理模块。给出了具体的实验方法和实验过程,对改进原理和实验数据...
lucene,lucene教程,lucene讲解。 为了对文档进行索引,Lucene 提供了五个基础的类 public class IndexWriter org.apache.lucene.index.IndexWriter public abstract class Directory org.apache.lucene.store....
lucene3.0 lucene3.0 lucene3.0 lucene3.0 lucene3.0
lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习lucene学习...
描述了Lucene中如何使用FST算法构建term的内存索引,使用了很多图,直观的展现了FST图的构建流程,能够对想了解lucene内部实现机制原理的同学有帮助。
Lucene3.0特性Lucene3.0特性
对Lucene内部的相似度评分算法进行研究分析后,针对Lucene只关心查询词出现的频率,而不关心它们所在的位置这一缺陷提出了一种改进的算法。改进的算法将词语位置关系特征融合到Lucene原始相似度评分算法中。在TREC...
lucene学习教程lucene讲义 叫你用lucene算法
lucene3源码分析
lucene
lucene
lucene.NET 中文分词 高亮 lucene.NET 中文分词 高亮 lucene.NET 中文分词 高亮 lucene.NET 中文分词 高亮
在lucene中使用庖丁解牛的分词器,实现类似当当网站的功能实现一个对企业内部产品的检索功能
Annotated Lucene 中文版 Lucene源码剖析
《Lucene实战(第2版)》基于Apache的Lucene 3.0,从Lucene核心、Lucene应用、案例分析3个方面详细系统地介绍了Lucene,包括认识Lucene、建立索引、为应用程序添加搜索功能、高级搜索技术、扩展搜索、使用Tika提取文本...
Lucene 正则表达式 regexQuery
本课程由浅入深的介绍了Lucene4的发展历史,开发环境搭建,分析lucene4的中文分词原理,深入讲了lucenne4的系统架构,分析lucene4索引实现原理及性能优化,了解关于lucene4的搜索算法优化及利用java结合lucene4实现...