我有一个jcr存储库(带有嵌入式servlet容器),它使用lucene进行全文搜索。搜索查询似乎会触发cpu利用率的峰值,即使在搜索结果返回后也会停留相当长的时间。我接受了线程转储并意识到Lucene Merge线程导致cpu出现峰值。
"Lucene Merge Thread #0" daemon prio=10 tid=0x000000005fd95000 nid=0x5add runnable [0x0000000049fc8000]
java.lang.Thread.State: RUNNABLE
at org.apache.lucene.store.IndexOutput.writeVInt(IndexOutput.java:70)
at org.apache.lucene.index.FormatPostingsPositionsWriter.addPosition(FormatPostingsPositionsWriter.java:70)
at org.apache.lucene.index.SegmentMerger.appendPostings(SegmentMerger.java:701)
at org.apache.lucene.index.SegmentMerger.mergeTermInfos(SegmentMerger.java:635)
at org.apache.lucene.index.SegmentMerger.mergeTerms(SegmentMerger.java:573)
at org.apache.lucene.index.SegmentMerger.merge(SegmentMerger.java:156)
at org.apache.lucene.index.IndexWriter.mergeMiddle(IndexWriter.java:4443)
at org.apache.lucene.index.IndexWriter.merge(IndexWriter.java:4000)
at org.apache.lucene.index.ConcurrentMergeScheduler.doMerge(ConcurrentMergeScheduler.java:231)
at org.apache.lucene.index.ConcurrentMergeScheduler$MergeThread.run(ConcurrentMergeScheduler.java:288)
行为非常一致。搜索查询反复似乎触发了合并(最终减慢了搜索本身),这对我来说很难理解为什么搜索会触发索引合并。
另一个相关问题是搜索查询在一段时间内变慢。重新启动服务器后,lucene查询将在大约300-400ms内返回,但如果服务器已运行一周,则相同的查询有时需要3-4s甚至更多。我检查了cpu&记忆。当服务器空闲时,cpu使用率是正常的(低于1%),但是一些搜索将cpu使用率发送到100%已有相当长的时间(见上文)。服务器有12g内存,其中目前只使用4g(因此没有内存问题)。那么为什么服务器运行一段时间后搜索会变慢(与重启相比)?是因为慢慢地缓存是随着时间的推移填充的,并且正在缓存上进行线性扫描(但缓存检索应该非常快 - 缓存的目的) [EDITED] 它的CRX 2.3支持JCR 2.0(JSR 283规范)。该存储库有大约40k个文件,其中大约15k是pdf,它们是为全文索引的。
答案 0 :(得分:0)
在查看lucene指数后检查你的lucene连接。如果未正确关闭,则会引发内存异常。
答案 1 :(得分:0)
您使用的是SimpleFSDirectory
还是RAMDirectory
?使用MMapDirectory
。
当我们使用RAMDirectory
时,它会将整个索引或大部分内容加载到作为虚拟内存的“内存”中。由于物理内存有限,操作系统当然可以决定换出我们的大RAMDirectory
。因此RAMDirectory
优化索引加载时间不是一个好主意。
另一方面,如果我们不使用RAMDirectory
缓冲索引并使用NIOFSDirectory
或SimpleFSDirectory
,我们必须支付另一个价格:我们的代码必须执行很多系统调用到O / S内核来复制磁盘或文件系统缓存与驻留在Java堆中的缓冲区之间的数据块。这需要一遍又一遍地在每个搜索请求上完成。
要解决上述所有问题MMapDirectory
使用虚拟内存和名为“mmap”的内核功能来访问磁盘文件。
同时检查link。