【问题标题】:high cpu usage on search over lucene index通过 lucene 索引搜索时 CPU 使用率较高
【发布时间】:2012-09-09 21:15:37
【问题描述】:

我有一个使用 lucene 进行全文搜索的 jcr 存储库(带有嵌入式 servlet 容器)。搜索查询似乎触发了 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 使用率发送到 100% 很长一段时间(见上文)时,cpu 使用率是正常的(低于 1%)。服务器有 12g 的内存,其中只有 4g 当前正在使用(所以没有内存问题)。那么为什么服务器运行一段时间后搜索会变慢(与重新启动相比)?是因为随着时间的推移缓慢地填充缓存并且正在对缓存进行线性扫描(但缓存检索应该非常快 - 缓存的目的) [编辑] 它的 CRX 2.3 支持 JCR 2.0(JSR 283 规范)。该存储库有大约 40k 个文件,其中大约 15k 是 pdf,它们被索引为全文。

【问题讨论】:

  • 您能否添加一个示例,说明您正在针对哪个 JCR 实现执行什么样的查询?
  • 它的 CRX 2.3 支持 JCR 2.0(JSR 283 规范)。该存储库有大约 40k 个文件,其中大约 15k 是 pdf,它们被索引为全文。
  • 您能添加您的 Lucene 搜索和索引代码吗?

标签: lucene cpu-usage jcr


【解决方案1】:

查看 lucene 索引后检查您的 lucene 连接。如果没有正确关闭它会抛出内存异常。

【讨论】:

    【解决方案2】:

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

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

    另一方面,如果我们不使用RAMDirectory 来缓冲我们的索引并使用NIOFSDirectorySimpleFSDirectory,我们必须付出另一个代价:我们的代码必须对O 执行大量系统调用/S 内核在磁盘或文件系统缓存和我们驻留在 Java 堆中的缓冲区之间复制数据块。这需要在每个搜索请求上一遍又一遍地完成。

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

    也检查这个link

    【讨论】:

    • 您能否编辑您的帖子以简要说明链接?如果将来链接失效,那么您的答案将更难理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-06
    • 2011-07-16
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多