问题:
目前索引里面已经有1000多万的数据了,现在需要每几分钟就增量得添加新的内容到索引中。
但是,我发现新加入索引后,整个索引结构都要重新调整。非常耗时(长达半个小时)。

不知道大家有没有什么比较好的办法,加快这个过程?


回答:

我觉得用lucene做,一个原则索引里面尽量少存储,索引文件小了,optimize要移动的数据块也小。
还有Lucene实在不适合做实时,有一个办法,将新索引建在内存中,新建在内存上的searcher与硬盘索引searcher合并为MutliSearcher提供给前端搜索,内存到达一定量时再后台合并到主索引上,合并完成用新的Searcher替换MutliSearcher。
Lucene2.3已经放出来了,添加了很多新功能,可以去看看

 

大量索引的更方案: 索引分开, 周索引,月索引,全部索引

 

提高搜索性能方式

搜索
1、对于按创建时间的排序可以使用doc.id的方式
new SortField(null, SortField.DOC, reverse)排序方式尽量使用INT类型的字段
也就是按照写入索引的顺序排序
2、对于时间字符串的排序可以转换成整数进行排序
3、去掉不必要的parse
使用TermQuery替换
4、TermQuery和Term可以只保留一个实例
createTerm(text)
5、减少Doc到model的转换
索引出来String到Date的转换多余而且费时
直接使用Doc对象包装成JSONObject
6、MultiFieldQueryParser改成自己用boolean查询重构
7、减少请求参数的包装类
8、搜索排序方法可以作为常量
将sort参数变成int型,使用swich进行判断
10、使用HitCollector类来适应不同情况下,Hits的大小
新、旧接口
相关搜索接口
11、使用尽可能快的磁盘IO
12、日志,先写文件,每天批量入库
13、增量索引使用reopen
新的reopen()方法只会加载那些变更过的索引片断,而不是重新加载完整的索引。
14、setMergeFactor 在做实时索引的时候,可以设置的小一点
这样就会及时索引进去


索引
索引
1、t.termText()替换为new String(t.termBuffer(),0,t.termLength())
2、StringReader 和TokenStream对象都需要close
3、索引时Document只用一个、Field只用几个
一个Document对象对应多个Field实例
Field有新的setValue方法,动态改变属性
不能只有一个Field实例
例如:idField, bodyField
必须等Document都到索引中之后,才可以重新设置值
4、索引中Field的命名只使用2个字符表示
5、有些索引字段可以考虑使用0,1替代字符串,排序采用整数来排
6、减少索引的存储字段,一般只存ID
7、索引的时候只用一个IndexWriter对象
8、3.1版本有个新的方法writer.ramSizeInBytes()
根据RAM的使用情况,来决定是不需要刷新到磁盘。
之前:setMaxBufferedDocs
9、批量索引的时候,尽可能多使用一些内存,采用非复合的文件方式,完成后集中优化合并索引文件
fsWriter.addIndexesNoOptimize
fsWriter.setUseCompoundFile(false);
需要注意不要超过系统的允许打开文件数
10、重复使用单一的Token实例,在analyzer中。
11、Turn off auto-commit if there are stored fields and term vectors
设置autoCommit=false,直到writer close之后才会生效
默认是true
12、如果总是同时在多个分词的字段中查询,可以考虑将多个Field合并到一个Field中
13、增加mergeFactor,但是不要太大
反复调试获取经验值
14、关闭一些实际上没用的功能(不要存储一些不必要的字段,尽量不要打开term vectors)
15、使用更快的analyzer
16、加快获得document数据的速度
比如:从数据库、文件获取数据的速度
17、索引的时候可以考虑使用多线程
使用多线程addDocuments
需要测试,然后确定线程数
18、可以分开索引,然后合并
并行索引机制