#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 мс, что кажется стандартным в соответствии с документами. Возможно, к считывателям индексов напрямую обращается приложение. Я рассмотрю это.