Руководство по производительности индексации Elasticsearch: лучшие практики
Улучшите производительность индексации Elasticsearch с помощью пакетных запросов, настройки обновления и реплик, выбора маппинга, проверки оборудования и планирования шардов.
Руководство по производительности индексации Elasticsearch: лучшие практики
Производительность индексации Elasticsearch становится заметной, когда ваш конвейер загрузки начинает отставать, пакетные запросы отклоняются или поиск замедляется во время интенсивной записи. Решение редко заключается в одной магической настройке; вам нужно настроить размер запроса, поведение обновления, маппинги, расположение шардов и оборудование вместе.
Это руководство сосредоточено на практических проверках производительности индексации Elasticsearch, которые можно применить до и во время крупной задачи загрузки. Используйте их с метриками из вашего собственного кластера, потому что размер документа, анализаторы, хранилище и количество реплик могут изменить результат.
Понимание процесса индексации
Прежде чем углубляться в оптимизацию, важно понять, как Elasticsearch обрабатывает индексацию. Когда документ индексируется, Elasticsearch выполняет несколько операций: разбор документа, анализ полей (токенизация, стемминг и т.д.), а затем сохранение инвертированного индекса и других структур данных. Эти операции, особенно анализ и ввод-вывод на диск, требуют интенсивного использования ЦП и ввода-вывода. В распределенной среде эти операции обрабатываются отдельными узлами, что делает конфигурацию кластера и ресурсы узлов критически важными.
Ключевые факторы, влияющие на скорость индексации
Несколько факторов могут значительно повлиять на то, насколько быстро Elasticsearch может индексировать документы:
- Аппаратные ресурсы: ЦП, ОЗУ и особенно скорость ввода-вывода диска имеют первостепенное значение. SSD настоятельно рекомендуются вместо HDD из-за их превосходной производительности чтения/записи.
- Конфигурация кластера: Распределение шардов, настройки репликации и роли узлов играют роль.
- Стратегия индексации: Метод, используемый для отправки данных (например, запросы отдельных документов против Bulk API).
- Маппинг и типы данных: Как определены ваши поля и их соответствующие типы данных.
- Интервал обновления: Как часто данные становятся видимыми для поиска.
- Настройки Translog: Настройки долговечности для подтвержденных записей.
Оптимизация производительности индексации: лучшие практики
В этом разделе рассматриваются действенные стратегии для повышения пропускной способности индексации Elasticsearch.
1. Используйте Bulk API
Самая фундаментальная оптимизация для индексации — использование Bulk API. Вместо отправки отдельных запросов на индексацию, которые создают сетевые накладные расходы и затраты на обработку каждого запроса, Bulk API позволяет отправлять список операций (index, create, update, delete) в одном HTTP-запросе. Это значительно снижает задержку сети и улучшает общую пропускную способность.
Лучшие практики для Bulk API:
- Размер пакета: Экспериментируйте с размерами пакетов. Начните с небольших нагрузок, затем увеличивайте, наблюдая за задержкой индексации, давлением на память и отклонениями
429. Количество документов само по себе недостаточно, потому что один документ может быть крошечным, а другой — несколько мегабайт. - Параллелизм: Используйте несколько потоков или асинхронных клиентов для одновременной отправки пакетных запросов. Однако избегайте перегрузки кластера. Следите за использованием ЦП и ввода-вывода, чтобы найти оптимальное значение.
- Обработка ошибок: Реализуйте надежную обработку ошибок. Bulk API возвращает массив ответов, и вам нужно проверить статус каждой операции.
Пример пакетного запроса:
{ "index": { "_index": "my-index", "_id": "1" } }
{ "field1": "value1", "field2": "value2" }
{ "index": { "_index": "my-index", "_id": "2" } }
{ "field1": "value3", "field2": "value4" }
2. Настройте параметры индексации
Elasticsearch предоставляет несколько настроек, которые можно изменить для оптимизации процесса индексации. Обычно они устанавливаются для каждого индекса.
Интервал обновления (index.refresh_interval)
Интервал обновления определяет, как часто данные становятся видимыми для поиска. Обычно активные индексы обновляются примерно раз в секунду, когда по ним выполняется поиск, но значения по умолчанию могут различаться в зависимости от версии и типа индекса. Во время интенсивной индексации вы можете увеличить этот интервал, чтобы уменьшить работу по обновлению. Установка значения -1 отключает автоматические обновления, что означает, что данные не станут доступными для поиска, пока вы не выполните ручное обновление или не восстановите автоматические обновления.
- Рекомендация: Для операций массовой индексации временно увеличьте
index.refresh_intervalили установите его в-1, когда свежесть поиска не требуется. После завершения массовой операции восстановите настройку, используемую для обычного поведения поиска, и при необходимости выполните ручное обновление.
Пример использования API настроек индекса:
# Временно отключить обновление
PUT /my-index/_settings
{
"index" : {
"refresh_interval" : "-1"
}
}
# ... выполнить массовую индексацию ...
# Включить обновление снова
PUT /my-index/_settings
{
"index" : {
"refresh_interval" : "1s"
}
}
Долговечность Translog (index.translog.durability)
Translog — это журнал упреждающей записи, который обеспечивает долговечность данных. Он может быть установлен в request (по умолчанию) или async. Установка async выполняет сброс translog асинхронно, что может улучшить скорость индексации, но несет небольшой риск потери данных, если узел выйдет из строя до того, как translog будет записан на диск.
- Рекомендация: Для сценариев массового импорта, где долговечность менее критична, чем скорость,
asyncможет быть полезен. Всегда учитывайте допустимость потери данных в вашем приложении.
Количество реплик (index.number_of_replicas)
Реплики — это копии ваших первичных шардов, используемые для высокой доступности и масштабирования чтения. Однако каждая реплика должна обрабатывать каждую операцию индексации. Во время начальной загрузки больших объемов данных установка index.number_of_replicas в 0 может значительно ускорить индексацию. После загрузки данных вы можете увеличить количество реплик.
Пример во время массовой загрузки:
# Временно установить реплики в 0
PUT /my-index/_settings
{
"index" : {
"number_of_replicas" : "0"
}
}
# ... выполнить массовую индексацию ...
# Восстановить реплики (например, до 1)
PUT /my-index/_settings
{
"index" : {
"number_of_replicas" : "1"
}
}
3. Оптимизируйте маппинги
Маппинги определяют, как документы и их поля хранятся и индексируются. Плохо спроектированные маппинги могут привести к проблемам с производительностью.
- Избегайте динамического маппинга для больших наборов данных: Хотя динамический маппинг удобен, он может привести к взрыву маппингов и неожиданным типам полей. Определите явные маппинги для ваших индексов, особенно для данных с высоким объемом.
- Выбирайте подходящие типы данных: Используйте наиболее эффективные типы данных. Например,
keywordболее эффективен для точного сопоставления значений, чемtext, если не требуется полнотекстовый поиск. - Отключайте ненужные функции: Если вам не нужны такие функции, как
normsдля определенного поля (например, для точных совпадений или агрегаций), их отключение может сэкономить место и улучшить скорость индексации (norms: false). Аналогично, отключитеdoc_values, если они не нужны для сортировки или агрегаций по полю. Однакоdoc_valuesобычно полезны для агрегаций и сортировки, так что это нюансированное решение. - Поле
_source: Если вам не нужен исходный JSON-документ, отключение_sourceможет сэкономить дисковое пространство и немного ввода-вывода, но это предотвращает переиндексацию и усложняет отладку. Рассмотрите сжатие_source, если вы оставляете его включенным.
Пример маппинга (с явными типами и отключенными norms):
PUT /my-index
{
"mappings": {
"properties": {
"timestamp": {"type": "date"},
"message": {"type": "text", "norms": false},
"user_id": {"type": "keyword"}
}
}
}
4. Аппаратное обеспечение и инфраструктура
Даже при идеальных программных конфигурациях недостаточное аппаратное обеспечение ограничит скорость индексации.
- Дисковый ввод-вывод: Используйте быстрые SSD. NVMe SSD обеспечивают наилучшую производительность. По возможности избегайте сетевых хранилищ (NAS) для узлов индексации.
- ЦП и ОЗУ: Достаточное количество ядер ЦП необходимо для анализа, а большой объем ОЗУ помогает с кэшированием и общей производительностью JVM.
- Емкость приема и координации: Для очень высоких скоростей приема рассмотрите выделенные узлы приема для конвейеров или узлы координации для клиентского пакетного трафика. Узлы данных все равно выполняют фактическую работу по индексации, поэтому не лишайте их ЦП, памяти или дискового ввода-вывода.
- Сеть: Обеспечьте достаточную пропускную способность и низкую задержку между вашими клиентами и узлами Elasticsearch, а также между узлами в кластере.
5. Размер и количество шардов
Хотя это не является прямой настройкой индексации, количество и размер шардов влияют на производительность. Слишком много маленьких шардов может увеличить накладные расходы. И наоборот, один массивный шард может быть трудно управляемым и может плохо масштабироваться. Стремитесь к размеру шардов от 10 ГБ до 50 ГБ для оптимальной производительности, но это может варьироваться.
- Рекомендация: Планируйте количество первичных шардов до индексации больших объемов данных. Обычно не рекомендуется изменять количество первичных шардов в существующем индексе без переиндексации.
6. Управление жизненным циклом индекса (ILM)
Для данных временных рядов использование управления жизненным циклом индекса (ILM) имеет решающее значение. Хотя ILM в первую очередь помогает управлять индексами с течением времени (переключение, сжатие, удаление), действие переключения может быть настроено на создание новых индексов на основе размера или возраста. Это гарантирует, что индексы остаются в оптимальных диапазонах размеров, что косвенно улучшает производительность индексации.
- Переключение: Когда индекс достигает определенного размера или возраста, ILM может автоматически создать новый пустой индекс и переключить на него псевдоним потока данных. Это позволяет оптимизировать настройки для нового индекса (например, уменьшить количество реплик во время начальной массовой загрузки) и поддерживать активные индексы управляемыми.
Практический вывод
Начните с пакетной индексации, явных маппингов и достаточного дискового ввода-вывода. Для одноразовых загрузок ослабьте обновления и реплики только в том случае, если вы можете терпеть снижение свежести поиска или избыточность, затем восстановите нормальные настройки и проверьте состояние кластера. Продолжайте тестирование с вашими реальными документами; общие размеры пакетов и количество шардов — это только отправные точки.