原文链接:
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
分享到:
相关推荐
10. **性能调优**:通过分析源码,开发者可以了解到如何调整各种参数,如缓存大小、合并策略等,来优化Lucene的性能。 总的来说,深入学习Lucene 3.5.0的源码,可以帮助开发者掌握全文检索的核心技术,了解其内部...
1. **SegmentMerger 改进**: Lucene 3.0 中,`MergePolicy` 和 `MergeScheduler` 分离,提供更灵活的索引合并策略。 2. **N-gram 查询支持**: 新增了对 N-gram 查询的支持,增强了短语查询和部分匹配的能力。 3. *...
Lucene的段合并过程是其索引过程中的一个重要环节,涉及合并策略的选择、反向信息的合并以及具体的合并任务执行。段合并器执行合并存储域、合并标准化因子、合并词向量以及合并词典和倒排表等操作。 此外,Lucene的...
8. **性能优化**:Lucene提供了多种策略来优化索引和搜索性能,如分块索引、缓存机制、合并策略等。理解这些优化策略对于构建高性能的搜索系统至关重要。 9. **分布式搜索**:虽然3.0.3版本可能不包含完整的分布式...
4. **性能优化**:探讨如何提升搜索速度,包括内存管理、缓存策略和段合并策略。 5. **实战应用**:通过实例演示如何将 Lucene 集成到实际项目中,如 Web 应用或大数据搜索平台。 通过该课程,你不仅可以掌握 ...
这通过In-memory缓冲和段合并策略实现。 7. **多语言支持**:Lucene内置了多种语言的分析器,如英文的StandardAnalyzer和中文的SmartChineseAnalyzer,它们处理不同语言的文本特点,如词典分词和停用词过滤。 8. *...
9. **内存管理**:Lucene 3.0 对内存使用进行了优化,通过使用段合并策略,控制内存占用的同时保持索引的紧凑性。 10. **持久化存储**:索引数据被保存在磁盘上,Lucene 使用高效的文件格式如Lucene3x或Lucene4x...
- **IndexReader**和**IndexWriter**的优化选项,如合并策略和段合并大小控制。 7. **分布式搜索**: - **Solr**:基于Lucene的开源搜索服务器,支持分布式搜索和处理大量数据。 8. **扩展性和定制性**: - **...
4. **查询解析(Query Parser)**:Lucene 提供了一个强大的查询解析器,可以将用户输入的自然语言查询转换为内部查询对象。在 3.0 版本中,查询语法相对简单,支持布尔操作符(AND、OR、NOT)、短语查询、通配符...
在索引更新方面,Lucene采用了创新的增量索引策略,通过不断地创建新索引文件并定期合并,避免了因单个大索引文件更新导致的大量IO操作。这种设计提高了索引效率,同时保持了搜索性能的稳定。 总的来说,Lucene是一...
Segment合并策略在3.6.0版本中得到了改进,以平衡空间和时间效率。 5. **内存管理**:Lucene使用DocValues和Norms来存储字段数据,优化了内存使用,降低了GC压力。 6. **多线程支持**:Lucene 3.6.0支持多线程索引...
笔记(九)和(十)可能讨论了Lucene的更新和优化策略,包括增量索引、删除文档、合并段以及性能调优技巧。这部分内容对于确保搜索效率和保持索引的实时性至关重要。 总的来说,这份《Lucene开发指南》提供了从基础到...
Lucene 3.6.1是其历史版本之一,虽然现在有更新的版本,但3.6.1版本因其稳定性及对基础原理的清晰展现,仍然是学习Lucene内部机制的良好起点。 1. **索引过程** Lucene的索引过程主要包括文档分析、词项创建、倒排...
源码分析是理解Lucene工作原理的关键,通过阅读源码,我们可以了解其内部数据结构、算法和设计模式。 二、源码结构 1. **索引模块**:包括`IndexWriter`,负责构建和更新索引;`IndexReader`,用于读取索引;`...
合并策略决定了哪些段应该被合并,以及何时进行合并。合并过程涉及到旧段的读取、新段的写入以及删除标记的更新。这一过程需要精心设计,以确保系统的稳定性和性能。 综上所述,《C# Lucene.net原理与代码分析加强...
4.8.0版本对段合并策略进行了优化,提升了整体性能。 3. 倒排索引(Inverted Index):倒排索引是Lucene的核心,它将每个词项映射到包含该词项的文档集合。4.8.0版进一步优化了内存和磁盘空间的使用。 4. 查询解析...
3. **查询解析**:用户输入的查询字符串会被转换为内部表示,Lucene支持多种查询语法,如布尔查询、短语查询、前缀查询、范围查询等。 4. **搜索执行**:查询执行涉及对索引的遍历,通过Scorer计算文档与查询的相关...
例如,通过改进的位向量技术和更高效的段合并策略,降低了磁盘I/O,提高了性能。 2. **查询解析与执行**:Lucene提供了强大的查询语言支持,包括布尔查询、短语查询、近似查询等。6.4.0版本在查询解析器和执行引擎...
合并策略考虑了多个因素,如段的大小、文档数量以及系统资源的可用性。这一过程可能涉及重新索引和优化存储布局。 通过深入理解Lucene的原理与代码实现,开发者可以更好地优化搜索应用的性能,同时也能在遇到问题时...
1. **性能优化**:可以通过调整段的合并策略、缓存策略以及使用倒排索引压缩来提高搜索性能。 2. **扩展性**:Lucene本身不包含搜索结果排序、高亮显示等功能,但可以通过自定义`ScoreDoc`、`Highlighter`等实现...