Как можно избежать ошибок OutOfMemoryEr при обновлении документов в индексе Lucene? - PullRequest
2 голосов
/ 05 августа 2011

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

Для обновления измененных документов я удаляю эти документы с помощью IndexWriter.deleteDocuments(Query), а затем добавляю обновленные документы с помощью IndexWriter.addDocument().

Объект Query, используемый в IndexWriter.deleteDocuments, содержит приблизительно 12-15 терминов. В процессе обновления индекса мне также иногда необходимо выполнить полное обновление, удалив все документы с помощью IndexWriter.deleteDocuments, а затем добавив новые документы.

Проблема в том, что когда я позвонил IndexWriter.flush() после, скажем, около 100000 удалений документов, выполнение занимает много времени и выдает OutOfMemoryError. Если я отключаю очистку, индексация идет быстро, например, 2000000 удалений документов, а затем выдает OutOfMemoryError. Я попытался установить IndexWriter.setRAMBufferSizeMB на 500, чтобы избежать ошибки нехватки памяти, но безуспешно. Размер индекса составляет 1,8 ГБ.

Ответы [ 3 ]

1 голос
/ 05 августа 2011

First . Увеличение буфера оперативной памяти не ваше решение. Насколько я понимаю, это кеш, и я бы скорее сказал, что это увеличивает вашу проблему. OutOfMemoryError - это проблема JVM, а не проблема Lucene. Вы можете установить буфер ОЗУ на 1 ТБ - если вашей виртуальной машине не хватает памяти, у вас все равно есть проблема. Таким образом, вы можете сделать две вещи: увеличить память JVM или уменьшить потребление.

Второй . Вы уже рассматривали возможность увеличения настроек кучи памяти? Причина, по которой очистка выполняется вечно, заключается в том, что система выполняет много сборок мусора незадолго до того, как ей не хватит памяти. Это типичный симптом. Вы можете проверить это с помощью такого инструмента, как jvisualvm. Сначала нужно установить плагин GC details, но затем вы можете выбрать и контролировать свое сумасшедшее приложение OutOfMemory. Если вы узнали о проблеме с памятью, вы можете увеличить максимальное пространство кучи следующим образом:

java -Xmx512M MyLuceneApp (или как вы запускаете приложение Lucene)

Но, опять же, я бы сначала использовал инструменты для проверки вашего профиля потребления памяти и поведения сборки мусора. Ваша цель должна состоять в том, чтобы избежать нехватки памяти, потому что это приводит к тому, что сборка мусора замедляет работу вашего приложения до бездействия.

Третий . Теперь, если вы увеличиваете свою кучу, вы должны быть уверены, что у вас также достаточно родной памяти. Потому что, если вы этого не сделаете (проверьте с помощью таких инструментов, как top в Linux), ваша система начнет переключаться на диск, и это также скажется на производительности Lucene, как на сумасшедшей. Поскольку Lucene оптимизирован для последовательного чтения с диска, и если ваша система начинает подкачку, ваш жесткий диск будет выполнять поиск дисков, который на 2 порядка медленнее, чем последовательное чтение. Так будет еще хуже.

Четвертый . Если вам не хватает памяти, рассмотрите возможность удаления в пакетном режиме. После 1000 или 10000 документов сделайте флеш, потом снова и снова. Причина этой ошибки OutOfMemoryEr состоит в том, что Lucene должен хранить все в памяти, пока вы не выполните сброс. Так что в любом случае было бы хорошей идеей не допускать сброс слишком больших партий, чтобы избежать проблем в будущем.

0 голосов
/ 26 ноября 2016

Попробуйте использовать меньший RamBufferedSize для вашего IndexWriter.

IndexWriter очищает сброс, если буфер заполнен (или количество документов достигает определенного уровня).Установив большой размер буфера, вы неявно откладываете очистку вызова, что может привести к тому, что в памяти будет слишком много документов.

0 голосов
/ 05 августа 2011

В том (редком) случае, когда я хочу стереть все документы из моего индекса Lucene, я считаю, что гораздо эффективнее закрыть IndexWriter, удалить файлы индекса напрямую, а затем в основном запустить новый индекс.Операция занимает очень мало времени и гарантированно оставит ваш индекс в первоначальном (если несколько пустом) состоянии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...