Повільний 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-archive-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.
Що входить в аудит та оптимізацію під ключ за 5 днів
- Аналіз поточної конфігурації кластера (шарди, репліки, 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 день (від 200$) - Оптимізація шардингу та refresh: 2–3 дні - Глибока оптимізація запитів: 1–2 дніПишіть нам для оцінки вашого кластера — наші сертифіковані інженери з 5+ років досвіду гарантують прискорення пошуку в 2-5 разів. Замовте аудит продуктивності Elasticsearch та отримайте детальний звіт з рекомендаціями. Економія на інфраструктурі може сягати 30% (від 500$ на місяць). Вартість аудиту від 200$, а повна оптимізація під ключ — від 1000$ за 5 днів.
Elasticsearch Documentation — офіційний посібник із налаштування продуктивності.







