Оптимизация производительности в Solr

Обзор

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

Не существует универсального руководства по улучшению производительности, которое бы подходило для всех Solr-кластеров. 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 загружать поля, которые не запрашиваются напрямую, но могут понадобиться позже по мере необходимости. Это может повысить производительность, если большинство запросов запрашивают только небольшой список полей.

Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней