如何确保Solr / Lucene不会因java.lang.OutOfMemoryError而死?

时间:2010-03-06 07:43:01

标签: lucene jvm solr

我真的很困惑为什么它在索引期间一直死于java.lang.OutOfMemoryError,即使它有几GB的内存。

是否有一个根本原因需要手动调整配置文件/ jvm参数而不是只计算可用内存量并限制自己的内容?除了Solr之外,没有其他程序会遇到这种问题。

是的,每次发生此类崩溃时我都可以不断调整JVM堆大小,但这一切都是倒退。

以下是最新此类崩溃的堆栈跟踪,以防相关:

SEVERE: java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOfRange(Arrays.java:3209)
    at java.lang.String.<init>(String.java:216)
    at org.apache.lucene.index.TermBuffer.toTerm(TermBuffer.java:122)
    at org.apache.lucene.index.SegmentTermEnum.term(SegmentTermEnum.java:169)
    at org.apache.lucene.search.FieldCacheImpl$StringIndexCache.createValue(FieldCacheImpl.java:701)
    at org.apache.lucene.search.FieldCacheImpl$Cache.get(FieldCacheImpl.java:208)
    at org.apache.lucene.search.FieldCacheImpl.getStringIndex(FieldCacheImpl.java:676)
    at org.apache.lucene.search.FieldComparator$StringOrdValComparator.setNextReader(FieldComparator.java:667)
    at org.apache.lucene.search.TopFieldCollector$OneComparatorNonScoringCollector.setNextReader(TopFieldCollector.java:94)
    at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:245)
    at org.apache.lucene.search.Searcher.search(Searcher.java:171)
    at org.apache.solr.search.SolrIndexSearcher.getDocListNC(SolrIndexSearcher.java:988)
    at org.apache.solr.search.SolrIndexSearcher.getDocListC(SolrIndexSearcher.java:884)
    at org.apache.solr.search.SolrIndexSearcher.search(SolrIndexSearcher.java:341)
    at org.apache.solr.handler.component.QueryComponent.process(QueryComponent.java:182)
    at org.apache.solr.handler.component.SearchHandler.handleRequestBody(SearchHandler.java:195)
    at org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:131)
    at org.apache.solr.core.SolrCore.execute(SolrCore.java:1316)
    at org.apache.solr.servlet.SolrDispatchFilter.execute(SolrDispatchFilter.java:338)
    at org.apache.solr.servlet.SolrDispatchFilter.doFilter(SolrDispatchFilter.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:619)

8 个答案:

答案 0 :(得分:3)

查看堆栈跟踪,看起来您正在执行搜索,并按字段排序。如果需要按字段排序,则内部Lucene需要将字段中所有项的所有值加载到内存中。如果该字段包含大量数据,则很可能会耗尽内存。

答案 1 :(得分:2)

我不确定是否有一种坚定的方法可以确保您不会遇到Lucene的OutOfMemoryExceptions。您遇到的问题是与FieldCache的使用相关的问题。来自Lucene API“维护术语值的缓存”。如果您的条款超过分配给JVM的内存量,您将获得例外。

文档正在“org.apache.lucene.search.FieldComparator $ StringOrdValComparator.setNextReader(FieldComparator.java:667)”中进行排序,这将占用存储为其排序的术语所需的内存量。索引。

您需要查看可排序字段的预计大小,并相应地调整JVM设置。

答案 2 :(得分:0)

一个疯狂的猜测,您要编制索引的文档非常大

Lucene默认只对文档的前10,000个术语编制索引以避免OutOfMemory错误,您可以克服此限制,请参阅setMaxFieldLength

此外,您可以在完成使用Indexwriter()处理后立即调用optimize()并关闭

明确的方法是剖析并找到瓶颈=]

答案 3 :(得分:0)

您使用post.jar索引数据?我认为这个jar在solr1.2 / 1.3中有一个错误(但我不知道细节)。我们公司已经在内部对其进行了修复,并且应该在最新的主干solr1.4 / 1.5中进行修复。

答案 4 :(得分:0)

我正在使用这个Java:

$ java -version
java version "1.6.0"
OpenJDK  Runtime Environment (build 1.6.0-b09)
OpenJDK 64-Bit Server VM (build 1.6.0-b09, mixed mode)

哪个用完了堆空间,但后来升级到了这个Java:

$ java -version
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)

现在它工作得很好,在一个庞大的数据集上,有很多术语方面。

答案 5 :(得分:0)

对我而言,它在重启Tomcat服务器后起作用。

答案 6 :(得分:0)

  • 导航至C:\ Bitnami \ solr-4.7.2-0 \ apache-solr \ scripts
  • 打开serviceinstall.bat(使用notepad ++或其他程序)
  • 添加或更新以下属性: - ++ JvmOptions = -Xms1024M ++ JvmOptions = -Xmx1024M
    • 从该窗口的命令提示符处运行serviceinstall.bat REMOVE
    • 然后运行serviceinstall.bat INSTALL
    • 希望帮助!

答案 7 :(得分:0)

一个老问题,但是因为我偶然发现了它:

  1. 字符串字段缓存比Lucene 4.0更紧凑。所以很多人都可以适应。
  2. Field Cache是​​一种内存结构。所以无法阻止OOME。
  3. 对于需要排序或分面的字段 - 应该尝试DocValues来克服这个问题。 DocValues可以处理数字和非分析字符串值。我认为很多用于排序/分面的用例将具有这些值类型之一。