3

我不是 Java 人,但使用 Solr 进行搜索,但是在搜索了这个问题之后,我找不到它发生的原因。

我有一个没有排序的 3000 万条记录索引,并且是我能做的最简单的设置,但经过几次查询后出现以下异常:

严重:java.lang.OutOfMemoryError:org.apache.lucene.index.SegmentReader.fakeNorms(SegmentReader.java:1125) 处 org.apache.lucene.index.SegmentReader.createFakeNorms(SegmentReader.java:1117) 处的 Java 堆空间org.apache.lucene.index.SegmentReader.norms(SegmentReader.java:1140) 在 org.apache.solr.search.SolrIndexReader.norms(SolrIndexReader.java:282) 在 org.apache.lucene.search.TermQuery$TermWeight。 scorer(TermQuery.java:72) at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:250) at org.apache.lucene.search.Searcher.search(Searcher.java:171) at org.apache .solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:988) 在 org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:884) 在 org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:341) 在 org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:182) 在 org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:195) 在 org.apache .solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:131) 在 org.apache.solr.core.SolrCore.execute(SolrCore.java:1317) 在 org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java :338) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 在 org.apache.catalina.core 的 org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:241)。 ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 在 org.apache。catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java: 102) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) 在 org.apache.coyote.http11.Http11Processor 的 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) .process(Http11Processor.java:859) 在 org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java :489) 在 java.lang.Thread.run(Thread.java:679)在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 的 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 的调用(StandardHostValve.java:127)。 .catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) 在 org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) 在 org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol .java:602) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 在 java.lang.Thread.run(Thread.java:679)在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 的 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 的调用(StandardHostValve.java:127)。 .catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) 在 org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) 在 org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol .java:602) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 在 java.lang.Thread.run(Thread.java:679)connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java: 602) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 在 java.lang.Thread.run(Thread.java:679)connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java: 602) 在 org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 在 java.lang.Thread.run(Thread.java:679)

然后我重新启动tomcat,它会重新开始工作,直到有几个请求再次下降。

我没有排序(即使我希望它)和搜索操作系统大部分时间都是按特定的索引字段(不是所有的)。

你可以帮帮我吗?提前致谢 :)

4

2 回答 2

6

对于具有几百万条记录的 Solr 部署来说,128 MB 似乎很低。您确实可以使用-Xmx. 只是更改了调整堆大小的-XX:MinHeapFreeRatio点,但您也可以使用-Xms与直接分配最大大小相同-Xmx的值并避免任何调整大小。

但是,您可能希望尝试为堆确定更精确的值,而不是盲目地投入更多内存,因为过多的内存可能会适得其反,因为垃圾回收期间的暂停时间更长。使用 JVisualVM(更好的是,使用 VisualGC 插件)或jstat在命令行上,您可以看到 Solr 在启动后使用了多少内存,在请求后使用了多少,以及在您的典型使用过程中它的堆通常如何变化。

例如,使用jstat -gcutil <PID>,您可以看到 JVM 的年轻代(E,如 Eden)和老代 (O) 有多满(首先应该查看的是老一代)。或者使用jstat -gc <PID>,您将获得值而不是百分比(C 列是容量,即最大值,U 列是实际使用量)。您需要为 Solr 的工作集提供足够的内存以及处理请求所需的内存。使用该信息,您可以更精细地调整所需的内容。

于 2012-09-17T16:08:10.923 回答
0

看来您的代码中有内存泄漏。您可能需要进行堆转储以查看哪些对象正在消耗内存。

(或者)

正如布赖恩所说,您可能会以较少的内存配置启动tomcat。使用 -Xms 和 -Xmx 命令检查您为 tomcat 分配了多少内存。

于 2012-09-17T14:12:59.683 回答