Поиск в режиме гибернации проблемы со сборкой мусора Lucene

#java #hibernate #hibernate-search

#java #спящий режим #спящий режим-поиск

Вопрос:

У нас есть приложение Spring Boot, в котором запущен поиск в режиме гибернации 5.10.7.Final с серверной частью Lucene, и мы видим высокую загрузку процессора в одно и то же время каждый день.

Дамп потока показал, что потоки, потребляющие процессор, соответствуют активности по сборке мусора JVM:

 "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007fdef801f800 nid=0x173b runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007fdef8021800 nid=0x173c runnable
"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007fdef8023800 nid=0x173d runnable
"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007fdef8025000 nid=0x173e runnable
 

Дамп кучи показывает 2 экземпляра PeriodicRefreshingReaderProvider как самые большие объекты.

Существует также 3763 экземпляра org.apache.lucene.index.StandardDirectoryReader .

Я недостаточно знаком с поиском в режиме гибернации или Lucene, чтобы определить, является ли это типичным, и нам просто нужен больший размер кучи или что-то еще не так.

Текущий максимальный размер кучи составляет 12 ГБ (-Xmx). Индексы Apache Lucene занимают всего около 8 ГБ дискового пространства.

Настройки поиска в режиме гибернации

 hibernate.search.default.directory_provider = filesystem
hibernate.search.default.indexBase = /var/lucene/indexes
hibernate.search.default.reader.strategy = async
hibernate.search.default.reader.async_refresh_period_ms = 8000
 

введите описание изображения здесь

введите описание изображения здесь

Ответ №1:

Вы, по-видимому, используете async стратегию обновления, и карта, которая ссылается на всех открытых читателей, по-видимому, становится очень, очень большой.

Нет, это ненормально.

Вы упоминаете, что скачок процессора происходит каждый день в одно и то же время. Для чего вы установили период обновления? Т.е. каково значение свойства конфигурации hibernate.search.[default|<indexname>].reader.async_refresh_period_ms ? Если это действительно огромное значение, близкое к 24 часам, это может объяснить вашу проблему.

Считыватели индексов обычно не хранятся в течение такого большого количества времени, поэтому я полагаю, что возможно, что со временем они становятся очень большими. Если вы находитесь в такой ситуации, попробуйте сократить период обновления до чего-то более разумного, например, до 1 минуты или 5 минут: вы можете получать скачки процессора чаще, но гораздо меньшие, и вы будете использовать меньше памяти.

Кроме того, где-то может быть утечка чтения.

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

Вы случайно не обращаетесь к средствам чтения индексов явно в своем приложении? Через getIndexReaderAccessor()? Если это так, убедитесь, что вы правильно закрываете программы чтения. Если вы этого не сделаете, вы фактически пропускаете средства чтения индексов.

Комментарии:

1. Обновил мой пост с настройками поиска в режиме гибернации. Период обновления составляет 8 мс, что кажется стандартным в соответствии с документами. Возможно, к считывателям индексов напрямую обращается приложение. Я рассмотрю это.