在2.9之前,要看到index writer上发生的更新,必须关闭index writer,关闭动作会导致内部缓存的更新操作(生成新的segment,flush和commit,在硬盘上生成对应文件),然后再打开新的reader,才能看到更新。从2.9开始,Lucene开始引入near realtime search,可以在不关闭index writer的情况下,搜索到更新的内容。
实现原理
Near real time search的原理记录在LUCENE-1313和LUCENE-1516里。LUCENE-1313,在Index Writer内部维护了一个ram directory,在内存够用前,flush和merge操作只是把数据更新到ram directory,只有Index Writer上的optimize和commit操作才会导致ram directory上的数据完全同步到文件。LUCENE-1516,Index Writer提供了实时获得reader的API,这个调用将导致flush操作,生成新的segment,但不会commit(fsync),从而减少了IO。新的segment被加入到新生成的reader里。从返回的reader里,可以看到更新。所以,只要每次新的搜索都从Index Writer获得一个新的reader,就可以搜索到最新的内容。这一操作的开销仅仅是flush,相对commit来说,开销很小。
这里要清楚几个概念:lucene的index组织和flush,commit,optimize操作。
Lucene的index组织方式为一个index目录下的多个segment。新的doc会加入新的segment里,这些新的小segment每隔一段时间就合并起来。因为合并,总的segment数量保持的较小,总体search速度仍然很快。为了防止读写冲突,lucene只创建新的segment,并在任何active的reader不在使用后删除掉老的segment。
flush是把数据写入到操作系统的缓冲区,只要缓冲区不满,就不会有硬盘操作。
commit是把所有内存缓冲区的数据写入到硬盘,是完全的硬盘操作。
optimize是对多个segment进行合并,这个过程涉及到老segment的重新读入和新segment的合并,属于CPU和IO-bound的重量级操作。这是因为,Lucene索引中最主要的结构posting通过VINT和delta的格式存储并紧密排列。合并时要对同一个term的posting进行归并排序,是一个读出,合并再生成的过程。
代码解读(基于Lucene3.0)
在IndexWriter获得reader的方法中,主要调用了两个方法doflush()和maybeMerge()。doflush()将调用DocumentsWriter的flush方法,生成新的segment,返回的reader将能访问到新的segment。DocumentsWriter接收多个document添加,并写入到同一个segment里。每一个加入的doc会经过多个DocConsumer组成的流水线,他们包括StoredFieldsWriter(内部调用FieldsWriter),TermVec[color=red]torsTermsWriter,FreqProxTermsWriter,NormsWriter等。在外界没有主动调用flush的情况下,RAM buffer全用完了或者加入的doc数足够大后,才会创建新的segment并flush到目录中。
FreqProxTermsWriter调用TermHashPerField负责term的索引过程,当索引某字段词项时,使用对应TermsHashPerField的add()函数完成(一个)词项索引过程,并将索引内容(词项字符串/指针信息/位置信息等)存储于内存缓冲中。中间的过程使用了CharBlockPool,IntBlockPool,ByteBlockPool,只要内存够用,可以不断往后添加。
特性实验
设计一个文档检索程序,进程管理一个index writer和两个线程,线程A负责新文档的索引,线程B负责处理搜索请求,其中搜索时使用IndexWriter的新API获取新的reader。通过交替的生成index和search的请求,观察search的结果和索引目录的变化。实验结果如下:
打开indexwriter时,会生成一个lock文件
每次调用reader时,如果发生了更新,会先进行一次flush,把上次积攒在内存中的更新数据写成新的segment,多出一个.cfs。
从新的reader中,可以读到之前新加入的doc信息。
当新生成的segment达到十次后,会发生一次optimize,生成8个文件,为.fdt, .fdx, .frq, .fnm, .nrm, .prx, .tii, .tis。
当然,外界也可以主动触发optimize,结果是一样的。optimize前的多个segment的文件以及此前optimize的文件不再有用。
因为optimize生成cfs要消耗双倍磁盘空间,并增加额外的处理时间,当optimize的index大小较大,超过了index总大小的10或者一个规定大小时,即使index writer指定了CFS格式,optimize仍然会保留为多个文件的格式(LUCENE-2773)。
调用indexwriter的close方法,lock文件会被释放,但除了optimize的结果文件外,此前生成的文件并不会被删除。只到下次打开此index目录时,不需要的文件才会被删除。
当三种情况下,indexwriter会试图删除不需要的文件,on open,on flushing a new segment,On finishing a merge。但如果当前打开的reader正在使用文件,则不会删除。
因此,reader使用完后,一定要调用close方法,释放不需要的文件。
改进计划
In the future NRT may involve searching directly on the ram buffer without first encoding a full Lucene segment
参考资料
lucene官方对于near real time search的介绍
http://wiki.apache.org/lucene-java/NearRealtimeSearch
lucene-2.9.0 索引过程
http://blog.csdn.net/todaylxp/archive/2009/10/25/4726017.aspx
lucene的内存存储posting结构,增量式的posting内存存储结构,通过不同级别的多个内存块实现动态增加:
http://lucene-group.group.iteye.com/group/blog/587120
分享到:
相关推荐
1. **近实时搜索(Near Real-Time Search)**: 在 4.6.0 版本中,Lucene 引入了 Near Real-Time Search,即使在不断添加新文档时,也能快速反映出最新的搜索结果。 2. **多字段搜索(Multi-Field Search)**: 用户...
1. 近实时搜索(Near Real-Time Search):Lucene引入了Segment和Merge策略,能够在添加新文档后几乎立即反映到搜索结果中。 2. 分布式搜索(Distributed Search):通过Solr或Elasticsearch等工具,Lucene可以扩展...
此外,3.3.0版本可能还涉及一些当时的特性,比如N-gram分析器、近实时搜索(Near Real Time Search)或者改进的内存管理,这些都可以在实践中进一步探索。 总之,"Lucene3.3.0学习Demo"是一个宝贵的资源,对于想要...
- **近实时搜索(Near Real-Time Search)**:5.0引入了NRT(Near Real-Time)搜索,使得索引更新后的结果几乎立即可见,极大地提升了系统的响应速度。 - **多字段排序(Multi-field Sorting)**:允许根据多个...
- 近实时搜索:利用NRT(Near Real Time)机制,实现快速索引并立即生效的搜索。 - 高亮显示:搜索结果中高亮显示匹配的关键词,提高用户体验。 三、总结 通过对这些案例的源代码分析,我们可以深入理解Lucene的...
4. 实时更新:通过NRT(Near Real Time)模式,Lucene可以在不影响搜索性能的情况下实现数据的实时更新。 二、查询优化 1. 查询解析:理解并利用QueryParser的规则,如使用布尔运算符、通配符、短语查询等,可构造...
在性能优化方面,Lucene允许使用缓存(Caching)来加速频繁查询,使用分片(Sharding)来处理大规模数据,以及通过近实时搜索(Near Real-Time Search)来实现在新数据被添加后快速更新索引。 此外,Lucene还支持多...
- **近实时搜索**:通过NRTManager(Near Real Time Search)可以在不关闭索引的情况下快速看到新的或更新的文档。 - **多字段搜索**:允许用户在多个字段中同时进行搜索,提高查询的灵活性。 在实际应用中,可能还...
8. **高级特性**: Lucene还支持高级功能,如近实时搜索(Near Real-Time Search)、Faceted Search(分面搜索)、Spell Checking(拼写检查)和Highlighting(高亮显示)等。 9. **更新和优化**: Lucene允许对索引...
- 近实时搜索(Near Real Time Search)允许在索引更新后几乎立即看到变更。 Lucene的强大之处在于其灵活性和可扩展性,开发者可以通过自定义Analyzer和QueryParser实现特定的需求。通过不断优化和调整,可以在保持...
4. **实时索引**:结合NRT(Near Real Time)技术,可以在短时间内看到索引的更新。 总结,Lucene 3.0.2是一个强大的全文检索工具,它不仅提供了完整的搜索解决方案,还具备良好的可扩展性和灵活性,使得开发者能够...
8. **近实时搜索(Near Real-time Search)**: 虽然Lucene是基于磁盘的,但在3.6.2版本中,通过使用NRTManager,开发者可以实现近乎实时的搜索体验,即使在索引更新后也能快速反映到搜索结果中。 9. **文档更新与...
3. 近实时搜索:通过NRTManager(Near Real Time)机制,Lucene能在短时间内更新索引并反映到搜索结果中。 总结,Lucene提供了丰富的工具和接口,让开发者可以轻松实现复杂的文本处理和全文搜索功能。无论是简单的...
通过NRT(Near Real Time)机制,Lucene能够迅速反映索引的最新变化。即使在索引过程中,用户也可以通过`IndexReader`和`SearcherManager`获取到最新的搜索结果。 7. **多字段搜索** Lucene支持在一个文档中对多...
6. **实时更新**:通过NRT(Near Real Time)模式,Lucene能够在短时间内对索引进行更新并反映到搜索结果中。 **四、Lucene与其他工具的集成** Lucene可以与其他开源项目如Solr和Elasticsearch集成,提供更强大的...
8. **近实时搜索**:通过 NRT(Near Real-Time Search)机制,Lucene 可以在短时间内提供最新的搜索结果,即使在索引频繁更新的情况下。 9. **内存缓存**:Lucene 使用 DocValues 和 FieldCache 功能来缓存某些字段...
Lucene 4.6引入了近实时搜索(Near Real-Time Search)特性,允许在添加或更新文档后几乎立即返回最新结果。这得益于段合并优化和`NRTManager`的使用,后者管理`IndexReader`的生命周期,确保快速响应新添加的文档。...
2. **近实时搜索(Near Real Time Search)**:新添加的文档几乎立即可以被搜索到。 3. **多字段搜索**:可以基于多个字段进行复合查询。 4. **高亮显示**:突出显示搜索结果中的关键词。 5. **相似性...
7. **近实时搜索(Near Real-time Search)**: 新增或更新文档后,经过短暂延迟即可被搜索到。 **四、扩展与整合** Lucene 可以与其他开源项目结合,如 Solr 提供了 Web 接口和集群支持,Elasticsearch 建立在 ...
我们还可能探讨如何利用NRT(Near Real Time)搜索技术,使得新文档能够几乎实时地被搜索到。 在实际应用中,我们经常需要处理大量数据,因此分布式搜索是一个重要的话题。通过使用Solr或Elasticsearch等基于Lucene...