Медленный Elasticsearch — почти всегда результат неправильных настроек, а не недостатка железа. Лишние шарды убивают производительность надёжнее, чем слабые процессоры. Слишком частый refresh делает индексацию в 3–5 раз медленнее, чем нужно. Мы занимаемся оптимизацией Elasticsearch для наших клиентов уже более 5 лет — на нашем опыте 90% проблем решаются настройками, а не апгрейдом серверов. Оптимизация Elasticsearch — это прежде всего правильное проектирование, а потом уже тюнинг железа.
Как правильно настроить количество шардов?
Каждый шард — это отдельный экземпляр Lucene индекса со своими файловыми дескрипторами, JVM объектами, overhead на heap. На кластере с 5 узлами держать 500 маленьких индексов по 50 шардов каждый = 25 000 шардов = кластер ползает. Правило: 1 шард = 10–50 GB данных. Меньше — шарды слишком маленькие (overhead доминирует над данными). Больше — шард сложно перебалансировать при добавлении узла. Максимум шардов на 1 GB heap: ~20 шардов. При heap 16 GB = не более 320 шардов на узел.
Проверить статистику шардов можно командами _cat/shards и _cat/nodes. Уменьшение числа шардов через Shrink API требует отключения записи и перемещения всех шардов на один узел, затем выполняется _shrink.
Почему refresh_interval так важен?
Elasticsearch по умолчанию делает refresh каждую секунду — создаёт новый сегмент Lucene из буфера в памяти и делает документы доступными для поиска. Каждый refresh — файловые операции, создание сегмента, нагрузка на IO. Для real-time поиска (чат, уведомления) оставляйте 1s. Для аналитики, логов, ETL увеличьте до 30s–300s. При bulk-загрузке данных отключайте refresh на время: "index.refresh_interval": "-1". Прирост скорости индексации — 3–5x.
Merge Policy и forcemerge
Lucene периодически объединяет мелкие сегменты в крупные (merge). Это освобождает место от удалённых документов и ускоряет поиск. Для read-only индексов (архивные данные, завершённые rolling-индексы) форсировать merge до 1 сегмента:
POST /logs-2024.01.01/_forcemerge?max_num_segments=1 После forcemerge поиск значительно быстрее, а размер уменьшается на 20–40% за счёт удаления tombstone-записей. Не запускать forcemerge на активно индексируемых индексах — создаёт огромную IO нагрузку.
Реплики и Bulk API
Реплика — синхронная копия шарда на другом узле. При bulk-загрузке данных в новый индекс временно отключайте реплики: "index.number_of_replicas": 0. Прирост скорости — 2–3x при 1 реплике, 3–4x при 2 репликах. Bulk API — антипаттерн индексировать по одному документу. Используйте параллельную загрузку с размером пакета 5–15 MB. Пример на Python с parallel_bulk:
from elasticsearch import Elasticsearch from elasticsearch.helpers import parallel_bulk es = Elasticsearch([...]) def generate_actions(data): for item in data: yield {"_index": "products", "_source": item} for ok, info in parallel_bulk(es, generate_actions(data), chunk_size=500, max_chunk_bytes=10*1024*1024): if not ok: print(info) Оптимизация запросов
Filter vs. Query: используйте filter везде, где не нужен score. Фильтры кэшируются на уровне шарда. Wildcard и regexp — дорогие операции, особенно с leading wildcard. Заменяйте на edge N-gram. Deep pagination: from: 10000 — дорого. Используйте search_after с сортировкой.
Мониторинг и GC
Profile API — детальный разбор выполнения запроса. Hot Threads API — что делает JVM. При heap > 85% включается агрессивный G1GC, запросы тормозят. Настройте jvm.options для G1GC: -XX:+UseG1GC, -XX:G1ReservePercent=25, -XX:InitiatingHeapOccupancyPercent=30.
Что входит в аудит и оптимизацию
- Анализ текущей конфигурации кластера (шарды, реплики, refresh_interval, merge policy)
- Нагрузочное тестирование с профилированием запросов
- Рекомендации по шардингу и настройке refresh_interval
- Оптимизация запросов с использованием filter, search_after
- Настройка G1GC и heap
- Документация по изменениям и дальнейшая поддержка
| Параметр | Рекомендация | Комментарий |
|---|---|---|
| Размер шарда | 10–50 GB | Меньше — overhead, больше — сложно балансировать |
| Шардов на 1GB heap | ≤20 | 16GB heap → не более 320 шардов на узел |
| refresh_interval | 1s (real-time) / 30-300s (аналитика) / -1 (bulk) | Отключение refresh ускоряет индексацию в 3-5x |
| Реплики | 1 (HA) / 0 (bulk) | При загрузке отключать реплики |
| Forcemerge | Только для read-only индексов | Уменьшает размер на 20-40% |
Типовые сроки
- Аудит конфигурации: 1 день - Оптимизация шардинга и refresh: 2–3 дня - Глубокая оптимизация запросов: 1–2 дняСвяжитесь с нами для оценки вашего кластера — наши сертифицированные инженеры с 5+ лет опыта гарантируют ускорение поиска в 2-5 раз. Закажите аудит производительности Elasticsearch и получите подробный отчёт с рекомендациями. Экономия на инфраструктуре может достигать 30%.
Elasticsearch Documentation — официальное руководство по настройке производительности.







