Оптимизация производительности в Solr
Обзор
В данной статье описаны методы оптимизации и лучшие практики для повышения производительности вашего Solr-кластера.
Все рекомендации и оптимизации, описанные далее в статье, можно разделить на условные группы:
Настройка индекса
Правильные настройки индексирования позволяют Solr эффективнее хранить данные документов в файлах индекса Lucene и обеспечивают более быстрое выполнение запросов при поиске.
Параметры схемы
-
Выбирайте типы полей, которые наиболее точно соответствуют типу данных, хранимых в этих полях. Например, хранение дат в полях типа
DatePointField
, а неStrField
, может улучшить производительность как на этапе индексирования, так и при поиске. -
Сведите к минимуму использование полей типа
text_general
(TextField
) для хранения простых строк. Индексирование и поиск по полям такого типа запускает процессы токенизации/анализа для каждого запроса, что расходует вычислительную мощность. Вместо этого используйте поля типаstring
(StrField
) для сохранения строк без дополнительной обработки. -
Минимизируйте использование динамических полей (dynamic fields). Используя динамические поля, Solr может индексировать произвольные типы данных, которые не были явно определены в схеме. Однако такая гибкость влечет за собой дополнительные накладные расходы. Например, использование динамических полей — оптимальный выбор, если поле не всегда содержит значение либо когда тип поля может меняться от документа к документу.
-
Используйте docValues для полей, которые часто используются в сортировке или фасетировании (faceting).
-
При использовании кастомных полей указывайте параметры полей с учетом того, как поле будет использоваться в будущем при поиске. Основные рекомендации:
-
Избегайте большого количества полей с параметром
multiValued
. Данный параметр указывает, что документ может содержать несколько значений для типа поля. -
Не используйте свойство
stored=true
, если данное поле не используется для поиска. -
Используйте свойство
indexed=false
для полей, которые не задействованы при поиске или фильтрации.
-
Размер индекса
-
Избегайте записи избыточной и дублирующейся информации в индекс. Более подробная информация о предотвращении дубликатов доступна в статье Дедупликация в Solr.
-
Измените политику слияния (merge policy), которая определяет стратегию перезаписи нескольких сегмент-файлов Lucene в один. По умолчанию
TieredMergePolicy
объединяет сегмент-файлы примерно одинакового размера, с учетом допустимого количества сегментов в директории.
Репликация и шардирование
-
Используйте несколько Solr-шардов (shards), расположенных на разных хостах ADH, чтобы обрабатывать больше запросов одновременно. В индексе Solr, разбитом на шарды, документы распределяются по шардам таким образом, что каждый документ содержится только в одном шарде.
-
Используйте репликацию для обеспечения высокой доступности и отказоустойчивости.
Память и параметры JVM
Одним из важнейших факторов, влияющих на производительность Solr, является оперативная память. Solr требует достаточно памяти для области Java heap, а также дополнительно нуждается в свободной памяти для выполнения операций кеширования на уровне операционной системы.
-
Выделяйте достаточное количество памяти Java heap для каждого компонента Solr Server. Для этого используйте параметр Solr Server Heap Memory в ADCM (Clusters → <clusterName> → Services → Solr → Primary configuration). Однако просто выделение большего размера под heap не гарантирует ускорения производительности Solr. Heap Solr должен с запасом вмещать все внутренние объекты и кеши, оставляя при этом достаточно свободной памяти во избежание частых вызовов GC. Также в памяти хоста должно остаться место для операций кеширования на уровне ОС, чтобы кешировать данные индекса.
-
Выделяемый под heap размер памяти должен быть равен 40-70% от всей оперативной памяти хоста, часть памяти всегда должна оставаться свободной. Помимо heap, Solr использует off-heap память для более быстрого кеширования/записи данных документов в файлы индекса Lucene. Слишком большой heap может не оставить достаточно памяти для выполнения этих операций, делая их узким местом.
-
Анализируйте логи сборщика мусора (Garbage Collection, GC) для выявления аномалий и мониторинга использования памяти. По умолчанию Solr хранит логи GC в файлах /var/log/solr/solr_gc.log.*. Больше информации о логах Solr доступно в статье Логирование в Solr.
Параметры коммитов
Коммиты (commits) в Solr используются для того, чтобы сделать обновленные данные документа видимыми для поисковых запросов. Пока не выполнен коммит, обновления недоступны для поиска другими клиентами Solr. Solr выполняет два типа коммитов:
-
Жесткий коммит (hard commit). Делает обновления в документах видимыми для поиска, вызывая
fsync
для файлов индекса Lucene и записывая данные на диск. После выполнения жесткого коммита Solr прерывает текущий лог транзакций (transaction log) и открывает новый. -
Мягкий коммит (soft commit). Делает изменения индекса видимыми для поиска без вызова
fsync
для сегмент-файлов Lucene. После выполнения мягкого коммита обновленные данные документа продолжают записываться в лог транзакций, однако еще не сохраняются в сегмент-файл.
Мягкие коммиты являются хорошей опцией для получения результатов поиска в режиме "почти реального времени" (Near Real Time, NRT), поскольку они делают обновления видимыми другим клиентам с небольшой задержкой, не дожидаясь дорогостоящего жесткого коммита.
Жесткие коммиты необходимы для обеспечения надежности и гарантии того, что данные не будут потеряны, если хост внезапно выйдет из строя.
Настройки коммитов можно изменить в файле solrconfig.xml (блоки <autoCommit>
и <autoSoftCommit>
).
Используйте следующие рекомендации по настройке механизма коммитов:
-
Избегайте слишком частых жестких коммитов, так как их нагрузка на CPU и диск может сильно повлиять на общую производительность. Процесс записи на диск может стать основным узким местом при выполнении жестких коммитов, особенно если не хватает памяти для кеширования данных в page-кеше ОС. При выборе значения для автоматических жестких коммитов необходим баланс между как можно более редкими коммитами и соблюдением SLA доступности обновлений для поиска.
-
Хотя мягкие коммиты Solr "дешевле" жестких, они все равно потребляют определенное количество ресурсов процессора и памяти. Мягкие коммиты рекомендуется выполнять чаще, чем жесткие, но при этом необходимо соблюдать баланс между задержкой в обновлениях данных и скоростью индексации.
Оптимизация запросов
-
Сложные запросы могут замедлить работу Solr. Если ваш запрос содержит много фильтров и выполняется слишком долго, попробуйте разбить его на два более коротких.
-
При необходимости изменяйте поведение кеширования запросов. Solr автоматически кеширует частые и повторяющиеся запросы. Время, затрачиваемое на создание такого кеша, называется временем разогрева кеша (cache warm-up). Однако, когда данные записываются в Solr, все кеши сбрасываются после каждого коммита и должны быть заново прогреты, что потребляет ресурсы. Используйте параметр
autowarmCount=0
для настроек<filterCache>
,<queryResultCache>
и<documentCache>
в вашем solrconfig.xml, чтобы уменьшить количество циклов прогрева кеша. -
Не используйте слишком много фильтров в одном поисковом запросе.
-
Избегайте использования дорогостоящих операций, таких как поиск по подстановочным знакам в начале термина.
-
Используйте "ленивую" загрузку полей (параметр
<enableLazyFieldLoading>
), что позволяет Solr загружать поля, которые не запрашиваются напрямую, но могут понадобиться позже по мере необходимости. Это может повысить производительность, если большинство запросов запрашивают только небольшой список полей.