Как убедиться, что Solr/Lucene не умрет с java.lang.OutOfMemoryError?

Я действительно озадачен, почему он продолжает умирать с java.lang.OutOfMemoryError во время индексирования, даже если он имеет несколько ГБ памяти.

Есть ли фундаментальная причина, по которой ему требуется ручная настройка параметров конфигурационных файлов /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)

Ответы

Ответ 1

Посмотрев на трассировку стека, похоже, что вы выполняете поиск и сортируете по полю. Если вам нужно отсортировать по полю, внутри Lucene необходимо загрузить все значения всех терминов в поле в память. Если поле содержит много данных, то очень возможно, что у вас может закончиться нехватка памяти.

Ответ 2

Я не уверен, что есть устойчивый способ убедиться, что вы не столкнетесь с OutOfMemoryExceptions с Lucene. Проблема, с которой вы столкнулись, связана с проблемой использования FieldCache. Из API Lucene "Поддерживает кеши терминальных значений". Если ваши условия превышают объем памяти, выделенной для JVM, вы получите исключение.

Документы сортируются "по адресу org.apache.lucene.search.FieldComparator $StringOrdValComparator.setNextReader(FieldComparator.java:667)", который будет занимать столько памяти, сколько необходимо для хранения терминов, отсортированных для индекс.

Вам нужно будет просмотреть прогнозируемый размер полей, которые можно сортировать, и соответственно настроить параметры JVM.

Ответ 3

дикая догадка, документы, которые вы индексируете, очень большие

Lucene по умолчанию индексирует только первые 10 000 терминов документа, чтобы избежать ошибок OutOfMemory, вы можете преодолеть этот предел, см. setMaxFieldLength

Кроме того, вы можете вызвать optimize() и закрыть, как только вы закончите работу с Indexwriter()

определенным способом является профиль и поиск узкого места =]

Ответ 4

Вы используете post.jar для индексации данных? Я думаю, что у этой банки есть ошибка в solr1.2/1.3 (но я не знаю деталей). Наша компания исправила это внутренне, и она также должна быть исправлена ​​в последнем корпусе solr1.4/1.5.

Ответ 5

Я использовал эту 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)

И теперь он отлично работает на огромном наборе данных с большим количеством термов.

Ответ 6

Для меня это работало после перезапуска сервера Tomcat.

Ответ 7

  • перейдите к C:\Bitnami\solr-4.7.2-0\apache-solr\scripts
  • открыть службуinstall.bat(с помощью блокнота ++ или другой программы)
  • Либо добавьте, либо обновите следующие свойства: - ++ JvmOptions = -Xms1024M ++ JvmOptions = -Xmx1024M
    • из командной строки в этом окне запустите serviceinstall.bat REMOVE
    • затем запустите serviceinstall.bat INSTALL
    • Надеюсь, что помогите!

Ответ 8

Старый вопрос, но так как я наткнулся на него:

  • Кэш String Field намного компактнее от Lucene 4.0. Так много может вписаться.
  • Полевой кэш - это структура в памяти. Поэтому не может помешать OOME.
  • Для полей, которые требуют сортировки или огранки - нужно попробовать DocValues ​​для решения этой проблемы. DocValues ​​работают с числовыми и неанализируемыми строковыми значениями. И я предполагаю, что многие случаи использования сортировки/огранки будут иметь один из этих типов значений.