在过去的几周中,我一直在努力将应用程序从Lucene 3.x升级到Lucene 4.x,以期提高性能。不幸的是,在经历了完整的迁移过程并进行了在线和文档中发现的各种调整之后,Lucene 4的运行速度明显慢于Lucene 3(〜50%)。在这一点上,我几乎没有任何想法,并且想知道是否有人对如何加快速度提出了任何建议。我什至不希望在3.x上有更大的改进。我很高兴能与之匹配并保持最新版本的Lucene。
<编辑>
为了确认没有任何标准迁移更改对性能造成负面影响,我将Lucene 4.x版本移植回了Lucene 3.6.2,并保留了较新的API,而不是使用自定义的ParallelMultiSearcher和其他不推荐使用的方法/类。
3.6.2中的性能比以前更快:
由于更新的Lucene API的优化和使用实际上提高了3.6.2的性能,因此,除了Lucene之外,这都不是问题。我只是不知道我还可以在程序中进行哪些更改以修复它。
编辑>
应用信息
一般处理
1)套接字监听器收到的请求
2)最多生成4个查询对象,并使用规范化的用户输入填充(查询的所有必需输入都必须存在,否则将不执行)
3)使用Fork/Join框架并行执行查询
4)聚合和其他简单的后处理
其他相关信息
4.x热点
方法自我时间(%)|自拍时间(毫秒)|自拍时间(以毫秒为单位的CPU)
java.util.concurrent.CountDownLatch.await()| 11.29%| 140887.219 | 0.0 <-这只是等待实际工作完成的tcp线程-您可以忽略它
org.apache.lucene.codecs.lucene41.Lucene41PostingsReader $ BlockDocsEnum。
org.apache.lucene.codecs.BlockTreeTerReader $ FieldReader $ SegmentTermsEnum $ Frame。
org.apache.lucene.codecs.lucene41.ForUtil.readBlock()| 6.91%| 86208.621 | 86208
org.apache.lucene.search.DisjunctionScorer.heapAdjust()| 6.68%| 83332.525 | 83332
java.util.concurrent.ExecutorCompletionService.take()| 5.29%| 66081.499 | 6153
org.apache.lucene.search.DisjunctionSucorer.afterNext()| 4.93%| 61560.872 | 61560
org.apache.lucene.search.Tercorer.advance()| 4.53%| 56530.752 | 56530
java.nio.DirectByteBuffer.get()| 3.96%| 49470.349 | 49470
org.apache.lucene.codecs.BlockTreeTerReader $ FieldReader $ SegmentTerEnum。
org.apache.lucene.codecs.BlockTreeTerReader $ FieldReader $ SegmentTerEnum.getFrame()| 2.77%| 34576.54 | 34576
org.apache.lucene.codecs.MultiLevelSkipListReader.skipTo()| 2.47%| 30767.711 | 30767
org.apache.lucene.codecs.lucene41.Lucene41PostingsReader.newTertate()| 2.23%| 27782.522 | 27782
java.net.ServerSocket.accept()| 2.19%| 27380.696 | 0.0
org.apache.lucene.search.DisjunctionSucorer.advance()| 1.82%| 22775.325 | 22775
org.apache.lucene.search.HitQueue.getSentinelObject()| 1.59%| 19869.871 | 19869
org.apache.lucene.store.ByteBufferIndexInput.buildSlice()| 1.43%| 17861.148 | 17861
org.apache.lucene.codecs.BlockTreeTerReader $ FieldReader $ SegmentTerEnum.getArc()| 1.35%| 16813.927 | 16813
org.apache.lucene.search.DisjunctionSucorer.countMatches()| 1.25%| 15603.283 | 15603
org.apache.lucene.codecs.lucene41.Lucene41PostingsReader $ BlockDocsEnum.refillDocs()| 1.12%| 13929.646 | 13929
java.util.concurrent.locks.ReentrantLock.lock()| 1.05%| 13145.631 | 8618
org.apache.lucene.util.PriorityQueue.downHeap()| 1.00%| 12513.406 | 12513
java.util.TreeMap.get()| 0.89%| 11070.192 | 11070
org.apache.lucene.codecs.lucene41.Lucene41PostingsReader.docs()| 0.80%| 10026.117 | 10026
org.apache.lucene.codecs.BlockTreeTerReader $ FieldReader $ SegmentTerEnum $ Frame.decodeMetaData()| 0.62%| 7746.05 | 7746
org.apache.lucene.codecs.BlockTreeTerReader $ FieldReader.iterator()| 0.60%| 7482.395 | 7482
org.apache.lucene.codecs.BlockTreeTerReader $ FieldReader $ SegmentTerEnum.seekExact()| 0.55%| 6863.069 | 6863
org.apache.lucene.store.DataInput.clone()| 0.54%| 6721.357 | 6721
java.nio.DirectByteBufferR.duplicate()| 0.48%| 5930.226 | 5930
org.apache.lucene.util.fst.ByteSequenceOutputs.read()| 0.46%| 5708.354 | 5708
org.apache.lucene.util.fst.FST.findTargetArc()| 0.45%| 5601.63 | 5601
org.apache.lucene.codecs.lucene41.Lucene41PostingsReader.readTermsBlock()| 0.45%| 5567.914 | 5567
org.apache.lucene.store.ByteBufferIndexInput.toString()| 0.39%| 4889.302 | 4889
org.apache.lucene.codecs.lucene41.Lucene41SkipReader。
org.apache.lucene.search.TermQuery $ TermWeight.scorer()| 0.32%| 4045.912 | 4045
org.apache.lucene.codecs.MultiLevelSkipListReader。
org.apache.lucene.codecs.BlockTreeTermsReader $ FieldReader $ SegmentTermsEnum $ Frame.loadBlock()| 0.31%| 3886.194 | 3886
如果您还有其他可能有用的信息,请告诉我。
最佳答案
对于关心或正在尝试执行类似操作(查询中的受控并行性)的任何人,我遇到的问题是IndexSearcher在每个分片的每个段中创建一个任务,而不是在每个分片中创建任务-我误读了Javadoc。
我通过在分片上使用forceMerge(1)限制了额外线程的数量来解决了这个问题。在我的用例中,这没什么大不了的,因为我当前不使用NRT搜索,但是它仍然为更新+从属同步过程增加了不必要的复杂性,因此我正在研究避免forceMerge的方法。
作为快速解决方案,我可能会扩展IndexSearcher并使其为每个阅读器而不是每个段产生一个线程,但是Lucene邮件列表中提出了“虚拟段”的概念。这将是一个更好的长期解决方案。
如果您想查看更多信息,可以在这里关注lucene邮件列表线程:
http://www.mail-archive.com/java-user@lucene.apache.org/msg42961.html
关于java - Lucene 4.x性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18882071/