Настройка для ускорения индексирования
Использование запросов bulk
Bulk-запросы обеспечат намного лучшую производительность, чем запросы индексирования отдельных документов. Чтобы определить оптимальный размер bulk-запроса, необходимо выполнить бенчмарк на одном узле с одним фрагментом. Сначала попробуйте проиндексировать 100 документов одновременно, затем 200, затем 400 и т. д., удваивая количество документов в bulk-запросе в каждом запуске бенчмарка. Когда скорость индексирования начнёт уменьшаться, вы узнаете, что достигли оптимального размера bulk-запроса для ваших данных. В случае равенства лучше ошибиться в сторону меньшего, чем большего количества документов. Следите за тем, чтобы слишком большие bulk-запросы не создавали проблем с памятью кластера при одновременной отправке большого их числа, поэтому рекомендуется избегать объёма запросов более пары десятков мегабайт на запрос, даже если запросы большего размера кажутся более эффективными.
Использование нескольких рабочих процессов/потоков для отправки данных в Elasticsearch
Один поток, отправляющий bulk-запросы, вряд ли сможет достичь максимальной скорости индексирования кластера Elasticsearch. Чтобы использовать все ресурсы кластера, следует отправлять данные из нескольких потоков или процессов. Помимо более эффективного использования ресурсов кластера, это должно помочь уменьшить стоимость каждого fsync.
Следите за кодами ответов TOO_MANY_REQUESTS (429) (EsRejectedExecutionException с клиентом Java), это способ, которым Elasticsearch сообщает, что не может справиться с текущей скоростью индексирования. В этом случае необходимо немного приостановить индексирование, прежде чем пытаться снова, желательно с случайным экспоненциальным отложенным выполнением.
Аналогично размеру bulk-запросов, только тестирование покажет оптимальное количество рабочих процессов. Это можно проверить, постепенно увеличивая количество рабочих процессов до тех пор, пока I/O или ЦП не будут насыщены в кластере.
Сброс или увеличение интервала обновления
Операция, делающая изменения видимыми для поиска (называемая обновлением), дорогостоящая, и частая её вызов при активной индексации может снизить скорость индексирования.
По умолчанию Elasticsearch периодически обновляет индексы каждую секунду, но только для индексов, получивших один или более запросов поиска в последние 30 секунд.
Это оптимальная конфигурация, если у вас нет или очень мало поискового трафика (например, менее одного запроса поиска каждые 5 минут) и вы хотите оптимизировать скорость индексирования. Это поведение направлено на автоматическую оптимизацию индексирования bulk по умолчанию, когда поисковых запросов нет. Чтобы отказаться от этого поведения, необходимо явно установить интервал обновления.
С другой стороны, если ваш индекс регулярно получает поисковые запросы, это поведение по умолчанию означает, что Elasticsearch будет обновлять ваш индекс каждую секунду. Если вы можете позволить себе увеличить время между индексированием документа и его видимостью, увеличение index.refresh_interval до большего значения, например, 30s, может помочь улучшить скорость индексирования.
Отключение реплик для начальной загрузки
Если у вас большой объём данных, которые вы хотите загрузить в Elasticsearch сразу, может быть полезно установить index.number_of_replicas на 0, чтобы ускорить индексирование. Отсутствие реплик означает, что потеря одного узла может привести к потере данных, поэтому важно, чтобы данные хранились в другом месте, чтобы эту начальную загрузку можно было повторить в случае возникновения проблем. После завершения начальной загрузки вы можете установить index.number_of_replicas обратно на исходное значение.
Если index.refresh_interval настроено в настройках индекса, это может помочь отключить его во время этой начальной загрузки и установить его обратно на исходное значение после завершения начальной загрузки.
Отключение подкачки
Вы должны убедиться, что операционная система не подкачивает процесс java, отключив подкачку.
Предоставление памяти кэш-памяти файловой системы
Кэш-память файловой системы будет использоваться для буферизации операций ввода-вывода. Следует обеспечить кэш-памяти файловой системы не менее половины памяти машины, на которой работает Elasticsearch.
Использование автоматически генерируемых идентификаторов
При индексировании документа, имеющего явный идентификатор, Elasticsearch нужно проверить, существует ли документ с тем же идентификатором в том же фрагменте, что является дорогостоящей операцией, и становится ещё более дорогостоящей по мере роста индекса. Используя автоматически генерируемые идентификаторы, Elasticsearch может пропустить эту проверку, что ускоряет индексирование.
Использование более быстрого оборудования
Если индексирование ограничено операциями ввода-вывода, необходимо рассмотреть предоставление больше памяти кэшу файловой системы (см. выше) или покупку более быстрых накопителей. В частности, твердотельные накопители известны своей большей производительностью по сравнению с жёсткими дисками. Всегда используйте локальное хранилище; удалённые файловые системы, такие как NFS или SMB, следует избегать. Также следует опасаться виртуализированного хранилища, например, Amazon’s Elastic Block Storage. Виртуализированное хранилище работает очень хорошо с Elasticsearch, и оно привлекательно, так как так быстро и просто настроить, но, к сожалению, оно на практике медленнее, чем выделенное локальное хранилище. Если вы размещаете индекс на EBS, обязательно используйте выделенные IOPS, иначе операции могут быстро ограничиться.
Разделите индекс по нескольким SSD, настроив массив RAID 0. Помните, что это увеличивает риск сбоя, поскольку отказ любого одного SSD приводит к уничтожению индекса. Однако это обычно правильный компромисс: оптимизируйте отдельные фрагменты для максимальной производительности, а затем добавьте реплики на разных узлах для обеспечения резервирования при сбоях узлов. Вы также можете использовать восстановление и создание резервных копий для резервного копирования индекса для дополнительной страховки.
Размер буфера индексирования
Если ваш узел выполняет только интенсивное индексирование, убедитесь, что indices.memory.index_buffer_size достаточно велик, чтобы обеспечить буфер индексирования не более 512 МБ на каждый фрагмент, выполняющий интенсивное индексирование (дальше производительность индексирования обычно не улучшается). Elasticsearch принимает это значение (процент кучи Java или абсолютный размер в байтах) и использует его в качестве общего буфера для всех активных фрагментов. Активные фрагменты естественным образом используют этот буфер больше, чем фрагменты, выполняющие лёгкое индексирование.
По умолчанию установлено значение 10%, которого часто достаточно: например, если вы предоставите JVM 10 ГБ памяти, она выделит 1 ГБ для буфера индекса, чего достаточно для размещения двух активно индексируемых фрагментов.
Использование межкластерной репликации для предотвращения отвлечения ресурсов поиска от индексирования
В рамках одного кластера индексирование и поиск могут конкурировать за ресурсы. Создав два кластера, настроив межкластерную репликацию для репликации данных из одного кластера в другой и перенаправив все поисковые запросы на кластер с индексами-следующими, деятельность поиска больше не будет отвлекать ресурсы от индексирования в кластере, где находятся индексы-лидеры.
Дополнительные оптимизации
Многие стратегии, описанные в Настройка для использования дискового пространства, также улучшают скорость индексирования.
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/tune-for-indexing-speed.html