在lucene索引上搜索时cpu使用率高

在lucene索引上搜索时cpu使用率高,lucene,cpu-usage,jcr,Lucene,Cpu Usage,Jcr,我有一个jcr存储库(带有嵌入式servlet容器),它使用lucene进行全文搜索。搜索查询似乎会触发cpu利用率的峰值,即使在搜索结果返回后,cpu利用率也会保持相当长的一段时间。我接受了线程转储,并意识到Lucene Merge线程导致了cpu的峰值 "Lucene Merge Thread #0" daemon prio=10 tid=0x000000005fd95000 nid=0x5add runnable [0x0000000049fc8000] java.lang.

我有一个jcr存储库(带有嵌入式servlet容器),它使用lucene进行全文搜索。搜索查询似乎会触发cpu利用率的峰值,即使在搜索结果返回后,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-400毫秒后返回,但如果服务器已运行一周,同样的查询似乎需要3-4秒甚至更长时间。我检查了cpu和内存。当服务器空闲时,cpu使用率是正常的(低于1%),但一些搜索会在相当长的一段时间内将cpu使用率发送到100%(见上文)。服务器有12g内存,目前仅使用4g(因此没有内存问题)。那么,为什么当服务器运行了一段时间后(与重启相比),搜索速度会变慢呢??是不是因为缓存的填充速度很慢,并且正在对缓存进行线性扫描(但是缓存检索应该非常快,这正是缓存的目的) [已编辑]
它的CRX2.3支持JCR2.0(JSR283规范)。该存储库大约有40k个文件,其中大约15k是PDF文件,这些文件被全文索引。

在查看lucene索引后检查lucene连接。如果未正确关闭,将引发内存异常。

在查看lucene索引后检查您的lucene连接。如果未正确关闭,它将引发内存异常。

您使用的是
SimpleFSDirectory
还是
RAMDirectory
?使用
MMapDirectory

当我们使用
RAMDirectory
时,它会将整个索引或大部分索引加载到“内存”中,即虚拟内存。由于物理内存有限,操作系统当然可能会决定调出我们的大型
RAMDirectory
。因此,
RAMDirectory
不是优化索引加载时间的好主意

另一方面,如果我们不使用
RAMDirectory
来缓冲我们的索引,而使用
NIOFSDirectory
SimpleFSDirectory
,我们必须付出另一个代价:我们的代码必须对O/S内核进行大量系统调用,以便在磁盘或文件系统缓存与驻留在Java堆中的缓冲区之间复制数据块。这需要在每次搜索请求时反复执行

为了解决上述所有问题,MMapDirectory使用虚拟内存和一个名为“mmap”的内核功能来访问磁盘文件


也请检查此项。

您使用的是
SimpleFSDirectory
还是
RAMDirectory
?使用
MMapDirectory

当我们使用
RAMDirectory
时,它会将整个索引或大部分索引加载到“内存”中,即虚拟内存。由于物理内存有限,操作系统当然可能会决定调出我们的大型
RAMDirectory
。因此,
RAMDirectory
不是优化索引加载时间的好主意

另一方面,如果我们不使用
RAMDirectory
来缓冲我们的索引,而使用
NIOFSDirectory
SimpleFSDirectory
,我们必须付出另一个代价:我们的代码必须对O/S内核进行大量系统调用,以便在磁盘或文件系统缓存与驻留在Java堆中的缓冲区之间复制数据块。这需要在每次搜索请求时反复执行

为了解决上述所有问题,MMapDirectory使用虚拟内存和一个名为“mmap”的内核功能来访问磁盘文件


也请检查这一点。

您是否可以添加一个示例,说明您正在针对哪个JCR实现执行哪种查询?它的CRX 2.3支持JCR 2.0(JSR 283规范)。该存储库大约有40k个文件,其中大约15k个是PDF文件,这些文件被全文索引。您可以添加您的Lucene搜索和索引代码吗?您可以添加一个示例,说明您正在针对哪个JCR实现执行哪种查询吗?它的CRX 2.3支持JCR 2.0(JSR 283规范)。该存储库大约有40k个文件,其中大约15k个是PDF文件,这些文件为全文编制了索引。你能添加你的Lucene搜索和索引代码吗?你能编辑你的文章简要解释一下链接吗?如果链接在将来消失,那么你的答案就更难理解了。你能编辑你的帖子来简要解释一下链接吗?如果链接在将来消失,那么理解你的答案将更加困难。