Подтвердить что ты не робот

Следует ли оптимизировать индекс после инкрементных индексов в Lucene?

Мы выполняем полные переиндексации каждые 7 дней (т.е. создаем индекс с нуля) по нашему индексу Lucene и инкрементным индексам каждые 2 часа или около того. Наш индекс насчитывает около 700 000 документов, а полный индекс занимает около 17 часов (что не является проблемой).

Когда мы делаем инкрементные индексы, мы только индексируем контент, который изменился за последние два часа, поэтому требуется гораздо меньше времени - около получаса. Тем не менее, мы заметили, что много времени (возможно, 10 минут) тратится на метод IndexWriter.optimize().

LuceneFAQ упоминает, что:

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

... но это, похоже, не дает никакого определения того, что означает "часто". Оптимизация - интенсивность процессора и ОЧЕНЬ интенсивная интенсивность ввода-вывода, поэтому мы предпочли бы не делать этого, если мы сможем справиться с этим. Сколько стоит запуск запросов на не оптимизированном индексе (я думаю, особенно в отношении производительности запросов после полного повторного индекса по сравнению с после 20 инкрементными индексами, где, скажем, было изменено 50 000 документов)? Должны ли мы оптимизировать после каждого инкрементного индекса, или это поражение производительности не стоит?

4b9b3361

Ответ 1

Mat, так как вам кажется, что у вас есть хорошая идея, как долго длится ваш текущий процесс, я предлагаю удалить optimize() и измерить влияние.

Изменились ли многие документы в этих двухчасовых окнах? Если только небольшая доля (50 000/700 000 составляет около 7%) постепенно индексируется, то я не думаю, что вы получаете большую ценность из optimize().

Некоторые идеи:

  • Не делайте инкрементного optimize() вообще. Мой опыт говорит, что вы все равно не видите огромного улучшения запросов.
  • Делайте optimize() ежедневно вместо 2-часовой.
  • Выполняйте optimize() во время малой громкости (что говорит javadoc).

И убедитесь, что вы проводите измерения. Эти изменения могут быть в темноте без них.

Ответ 2

Операция optimize считывает и записывает весь индекс, поэтому он интенсивно работает с IO!

Идея оптимизации операций состоит в том, чтобы повторно объединить все различные сегменты в индексе Lucene в один сегмент, что может значительно сократить время запроса, поскольку вам не нужно открывать и искать несколько файлов для каждого запроса. Если вы используете стандартную структуру файлов Lucene (а не комбинированную структуру), вы получаете новый сегмент за операцию фиксации; как я предполагаю, ваши реиндексы?

Я думаю, Matt имеет отличный совет, и я бы сказал, что все, что он говорит, будет управляться данными, которые у вас есть. Я бы сделал еще один шаг и только optmize a), когда вам нужно, и b) когда у вас низкий объем запросов.

Поскольку производительность запросов тесно связана с количеством сегментов в вашем индексе, простой ls -1 index/segments_* | count может быть полезным индикатором того, когда в оптимизации действительно требуется.

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

Ответ 3

В это письмо, Otis Gospodnetic советует не использовать оптимизацию, если ваш индекс видит постоянные обновления. Это с 2007 года, но при вызове optimize() в нем очень характерна операция ввода-вывода. Вы можете использовать более ступенчатый подход; a MergeScheduler