如何提高Lucene构建索引的速度 hans(汉斯) 2013-01-27 10:12

对于Lucene>=2.3:IndexWriter可以自行根据内存使用来释放缓存。调用writer.setRAMBufferSizeMB()方法设置缓存尺寸。确保你没有任何的遗留代码调用setMaxBufferedDocs方法,因为写入器可以根据两种情况一起释放缓存(哪个更早发生)。使用你可以提供的全部内存。
在释放缓存之前使用更多的内存,意味着Lucene写入更大的段,意味着延迟合并的发生。LUCENE-843中的测试发现,针对所测内容集合48MB内存是最优值,但是,你的应用可能有不同的最优值。关闭复合文件格式。
调用setUseCompoundFile(false)。创建复合文件格式在索引期间更花时间(在LUCENE-888的测试中表明会多花7-33%的时间)。但是,注意这将极大的增加索引和搜索时的打开的文件数,所以如果你的mergeFactor设置过大的话,可能会耗尽可打开文件数。复用Document类和Field类对象的实例。
Lucene 2.3为Field类增加了一个新方法setValue(...),这样你就可以修改一个Field类对象的值。这就允许你在许多添加的文档之间复用同一 个Field类的实例,这样可以减少大量的GC开销。最好是,创建单个Document类的实例,然后把多个Field类实例加之于上,然后保持这些 Field类的实例,针对每个加入的文档,修改他们的值复用他们。例如,你可能有一个idField,bodyField,nameField和 storeField等等。文档加入后,你就可以直接修改Field的值(idField.setValue(...),等等),然后把它们加入到你的对 象实例里。注意,你不能在一个Document内复用同一个Field,你应该在包含这个Field的Document加入到索引以后才修改Field的 值。参看Field了解细节。当你使用保存的字段或者词向量的时候,总是用相同的顺序把字段添加到你的文档。
Lucene的合并有一种优化,依赖于对保存的字段和词向量进行的批量复制,但是只有在段间字段名->数字的映射保持一致的情况下才能实施。未来的Lucene可能会试图自动进行相同的映射(参见LUCENE-1737),但是到目前为止,获得相同映射的唯一途径就是总是用相同的顺序把字段加到索引内的每个文档中。在analyzer内复用同一个Token实例。
analyzer通常都为序列中的每个term创建一个新的Token实例。你可以通过复用同一个Token实例的方法大幅节约GC的开销。在Token中使用char[] API取代String API来展现记号文本。 在Lucene 2.3中,Token可以把他的文本用一个char数组的片段来表示,这可以节省GC的在new和回收String实例时造成的开销。通过复用同一个Token实例以及char[] API你可以避免每个词新建的所有对象。参见Token了解详情。打开IndexWriter时,使用autoCommit=false选项。
在Lucene 2.3中,包含了对保存字段和词向量的文档的显著优化,可以减少对非常大索引文件的合并操作。对一个长时间运行的IndexWriter使用 autoCommit=false选项,你就可以得到显著的性能提升。注意,然而这样的话,搜索器就只能在IndexWriter关闭的时候才能读取到索 引的变化;如果你非常需要在写入索引的同时可以搜索到最新更新的内容,那么你应该使用autoCommit=true选项,或者周期性的关闭和重新打开 writer。不去索引大量小文本字段,而是把文本聚合成一个单一的“内容”字段,并且仅索引(你还是可以索引其他的字段)。增大mergeFactor(合并因子),但是不要太大。
mergeFactor越大段的合并则越晚,因为合并是索引中开销很大的一部分,所以这样做可以提高索引的速度。然而,这将降低搜索的速度,如果太大的话,你可能会耗尽文件描述符。太大的值也可能减缓索引速度,因为一次性合并越多的段,意味着越多的磁盘寻道。关闭所有你并未使用的特性。
如果你存储了字段,但是查询期间并不使用的话,那么不要存储他们。词向量亦如是。如果你索引了太多的字段,关闭这些字段的norm可以提高性能。使用更快的analyzer。
有时候,分析一个文档会花很长时间。例如,StandardAnalyzer非常耗时,尤其是在Lucene 2.2以下的版本的。如果你可以使用一个简单的analyzer,那么用它吧。加速document构建。
从外部系统(数据库,文件系统,爬虫爬取的网站)获取一个document内容的常常是非常耗时的。除非你真的需要(更快的搜索),否则不要优化。多个线程使用一个IndexWriter。
现代硬件高度并行(多核CPU,多通道内存架构,硬盘的内建指令队列,等等)。所以使用多线程添加文档多半会更快。即使是老的电脑,也经常在IO和CPU间存在并发。测试线程的数量选择性能最好的线程数量。索引分开不合并。
如果你的索引内容非常的多,你可以把你的内容分为N块,在不同的机器索引每个块,然后使用writer.addIndexesNoOptimize把它们和并为最终索引。使用Java profiler。
如果这些都失败了,profile你的程序找出时间耗费在哪里。我成功使用过一个非常简单的profiler叫做JMP。有很多java的profiler。往往你会很意外的发现,一些愚蠢的、意想不到的方法花费了那么多的时间。

如何提高Lucene构建索引的速度的更多相关文章

  1. lucene 加速索引建立速度

    加速 lucene 索引建立速度 ImproveIndexingSpeed

  2. Lucene构建索引时的一些概念和索引构建的过程

    在搜索文档内容之前要做的事情就是对从各种不同来源(网页,数据库,电子邮件等)的文档进行索引,索引的过程就是对内容进行提取,规范化(通过对内容进行建模来实现),然后存储. 在索引的过程中有几个基本的概念 ...

  3. 【Lucene实验1】构建索引

    一.实验名称:构建索引 二.实验日期:2013/9/21 三.实验目的: 1)        能理解Lucene中的Document-Field结构的数据建模过程: 2)        能编针对特定数 ...

  4. 【Lucene】Apache Lucene全文检索引擎架构之构建索引2

    上一篇博文中已经对全文检索有了一定的了解,这篇文章主要来总结一下全文检索的第一步:构建索引.其实上一篇博文中的示例程序已经对构建索引写了一段程序了,而且那个程序还是挺完善的.不过从知识点的完整性来考虑 ...

  5. lucene学习笔记:三,Lucene的索引文件格式

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源代码的一把钥匙. 当我们真正进入到Lucene源代码之中的时候,我们会发现: Lucene的索引过程, ...

  6. Solr4.8.0源码分析(10)之Lucene的索引文件(3)

    Solr4.8.0源码分析(10)之Lucene的索引文件(3) 1. .si文件 .si文件存储了段的元数据,主要涉及SegmentInfoFormat.java和Segmentinfo.java这 ...

  7. Solr4.8.0源码分析(8)之Lucene的索引文件(1)

    Solr4.8.0源码分析(8)之Lucene的索引文件(1) 题记:最近有幸看到觉先大神的Lucene的博客,感觉自己之前学习的以及工作的太为肤浅,所以决定先跟随觉先大神的博客学习下Lucene的原 ...

  8. Lucene学习总结之三:Lucene的索引文件格式(1)

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源代码的一把钥匙. 当我们真正进入到Lucene源代码之中的时候,我们会发现: Lucene的索引过程, ...

  9. lucene内存索引库、分词器

    内存索引库 特点 在内存中开辟一块空间,专门为索引库存放.这样有以下几个特征: 1)    因为索引库在内存中,所以访问速度更快. 2)    在程序退出时,索引库中的文件也相应的消失了. 3)    ...

随机推荐

  1. jacob 操作word

    1. 首先下载jacob-1.18.zip,解压后有两个文件jacob.jar 和 jacob.dll.需要把jacob.jar放到你工程的classpath中并且把jacob.dll放到jdk的bi ...

  2. OSG中相机参数的更改

    #pragma comment(lib, "osg.lib") #pragma comment(lib, "osgDB.lib") #pragma commen ...

  3. c++文件读写相关

    在看C++编程思想中,每个练习基本都是使用ofstream,ifstream,fstream,以前粗略知道其用法和含义,在看了几位大牛的博文后,进行整理和总结: 这里主要是讨论fstream的内容: ...

  4. 【POJ2752】【KMP】Seek the Name, Seek the Fame

    Description The little cat is so famous, that many couples tramp over hill and dale to Byteland, and ...

  5. IOS下双击背景, touchmove, 阻止页面背景scroll.

    ios prevent dblclick(tap) page scrollhtml add:("minimal-ui" is very important) <meta na ...

  6. dedecms修改templets为别的名字

    修改templets模板文件夹的方法: 首先找到系统配置文件common.inc.php,此文件存放在Include目录下,打开common.inc.php来修改默认模板目录templets, 查找: ...

  7. jQuery 元素移除empty() remove()与detach()的区别?

    @1.empty() 删除匹配元素集合中所有的后代字节点元素: <p>hello<span>world</span></p> $("p&quo ...

  8. 舵机的PWM控制学习随笔

    舵机的控制信号,对于脉宽调制信号的脉宽变换,常用的一种方法是采用调制信号获取有源滤波后的直流电压,但是需要50Hz(周期是20ms)的信号,这对运放器件的选择有较高要求,从电路体积和功耗考虑也不易采用 ...

  9. HDU2602 (0-1背包问题)

      N - 01背包 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u   Descri ...

  10. [转] Java 8的新特性

    简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性.在本文中我们将学习这些新特性,并用实际的例子 ...