Elasticsearch-кластер в продакшне: от выбора архитектуры до эксплуатации
Привет! Я Евгений Семёнов, и это я руковожу компанией ITFresh. За пятнадцать лет в IT мне довелось заглянуть в самые разные продакшн-кластеры Elasticsearch. Видел и простенькие single-node решения, которые ставят «для логов разработчиков», и настоящих монстров на 25 нод, ворочающих петабайтами данных. Кстати, интересный факт: большинство ELK-стэков наших клиентов обычно крутятся на восьми серверах Dell Xeon Platinum 8280, оснащённых 40G Mellanox, и расположены они в московском дата-центре МТС. Так что эта статья — по сути, мой личный рабочий конспект. Тут я собрал всё, что, на наш взгляд, должно быть в каждом по-настоящему боевом кластере.
Архитектура: роли нод
В Elasticsearch 8.x ноды теперь чётко делятся по ролям. И это не просто так! Нельзя игнорировать этот момент. Ведь если все три ваших ноды одновременно и мастера, и хранилища данных — ждите проблем: вы быстро получите узкие места и ненужные риски.
| Роль | Задача | Сколько нод |
|---|---|---|
| master | Управление кластером, кворум | 3 (нечётное) |
| data_hot | Свежие данные, активная запись | от 2, NVMe SSD |
| data_warm | Данные 7–30 дней, чтение | от 2, SATA SSD |
| data_cold | Архив, редкий доступ | 1–2, HDD |
| ingest | Pipeline обработки на входе | совмещать с data |
| coordinating | Балансировка запросов | опционально, за LB |
Если у вас проект среднего масштаба, скажем, 500 ГБ логов в день, мы обычно используем такую схему: три master-only ноды, три data_hot и две data_warm. Зачем так? Я всегда настаиваю на выделении master-only нод. Почему? Проще некуда: когда data-мастер перегружен, в пиковые моменты вы рискуете потерять кворум. И это очень неприятно!
Железо и ОС
- CPU: Data-ноды — 16+ ядер. Master — достаточно 8.
- RAM: 64 ГБ на data_hot, 32 ГБ на master и warm.
- Диск: data_hot — NVMe RAID0 или zero-RAID с репликацией через ES; warm — SATA SSD; cold — HDD.
- Сеть: минимум 10G между нодами, лучше 25/40G. Внутрикластерный трафик при recovery огромен.
- ОС: Ubuntu 22.04 LTS или RHEL/Rocky 9. Выключите swap:
swapoff -aи в /etc/fstab.
Установка на Rocky Linux 9
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
sudo tee /etc/yum.repos.d/elastic.repo <
Базовый elasticsearch.yml для master-ноды
cluster.name: itfresh-prod
node.name: es-master-01
node.roles: [ master ]
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 10.10.1.11
http.port: 9200
transport.port: 9300
discovery.seed_hosts:
- 10.10.1.11
- 10.10.1.12
- 10.10.1.13
cluster.initial_master_nodes:
- es-master-01
- es-master-02
- es-master-03
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: certs/transport.p12
xpack.security.transport.ssl.truststore.path: certs/transport.p12
xpack.security.http.ssl.enabled: true
xpack.security.http.ssl.keystore.path: certs/http.p12
На data_hot — меняем роль: node.roles: [ data_hot, data_content, ingest ]. На всех нодах одинаковые discovery.seed_hosts и initial_master_nodes (последнее только при первой инициализации).
Heap и JVM настройки
Heap ≤ 50% ОЗУ и строго ≤ 30–31 ГБ. На машине с 64 ГБ я ставлю 30 ГБ heap. Файл /etc/elasticsearch/jvm.options.d/heap.options:
-Xms30g
-Xmx30g
А вот почему не стоит давать JVM больше 31 ГБ: иначе она 'потеряет' compressed oops, указатели начнут раздуваться, и общая производительность рухнет. Запомните: если данных действительно много, решение одно — добавляйте новые ноды, а не пытайтесь увеличить heap.
Лимиты в systemd — /etc/systemd/system/elasticsearch.service.d/override.conf:
[Service]
LimitMEMLOCK=infinity
LimitNOFILE=65535
Шардинг и репликация
Ищите золотую середину с размером шардов. Не делайте их слишком мелкими — иначе получите кучу оверхеда. Но и не гонитесь за гигантами, ведь с огромными шардами восстановление данных превратится в пытку. Наша практика показала: оптимальный ориентир — это 20–50 ГБ на шард.
Для индексов логов всегда используйте ILM — это Index Lifecycle Management. И обязательно настройте роловер именно по размеру, так надёжнее и эффективнее.
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": { "actions": { "rollover": { "max_primary_shard_size": "30gb", "max_age": "7d" } } },
"warm": { "min_age": "7d", "actions": { "shrink": { "number_of_shards": 1 }, "forcemerge": { "max_num_segments": 1 } } },
"cold": { "min_age": "30d", "actions": { "searchable_snapshot": { "snapshot_repository": "s3-backup" } } },
"delete":{"min_age":"90d", "actions": { "delete": {} } }
}
}
}
Реплики (число number_of_replicas) — всегда минимум 1 в продакшне, иначе падение одной data-ноды = потеря данных. Для критичных индексов — 2.
Мониторинг
Что такое кластер без мониторинга? Да просто чёрный ящик! И вы ничего не увидите, пока он не сломается окончательно. Вот минимальный набор метрик, который должен быть обязательно:
- Статус кластера (green/yellow/red)? Если видите red — поднимайте алерт немедленно! Это критически важно.
- unassigned_shards > 0 дольше 10 минут.
- JVM heap > 85% на любой ноде.
- disk.percent превышает 80%? Это уже тревожный звоночек. Запомните: у Elasticsearch есть три 'водных уровня': 85% — это low watermark, 90% — high, а 95% — уже flood, когда всё совсем плохо. Лучше не доводить до крайности!
- pending_tasks > 10.
- Очереди в thread_pool (индексирующем и поисковом). Если они начинают расти, это верный признак того, что кластер не справляется с текущей нагрузкой.
Для мониторинга мы в ITFresh всегда используем проверенную связку: Prometheus, elasticsearch-exporter и, конечно, Grafana. И, кстати, не ищите готовые дашборды по всему интернету — стандартные шаблоны легко найти прямо в Grafana library по ID 266. Удобно, правда?
Снапшоты и восстановление
Копировать /var/lib/elasticsearch нельзя — файлы меняются, получите повреждённый индекс. Правильно — snapshot API. Настраиваем репозиторий (S3, NFS или локальный):
PUT _snapshot/backup-nfs
{
"type": "fs",
"settings": {
"location": "/mnt/backup/es",
"compress": true
}
}
PUT _slm/policy/daily
{
"schedule": "0 30 2 * * ?",
"name": "",
"repository": "backup-nfs",
"config": { "indices": ["*"], "ignore_unavailable": true },
"retention": { "expire_after": "30d", "min_count": 7, "max_count": 50 }
}
Делайте это обязательно: раз в квартал тестируйте восстановление на отдельный кластер. Не просто проверьте, что бэкапы есть, а поднимите их! Иначе очень скоро обнаружите, что ваши драгоценные копии лишь *казались* рабочими.
Реальный кейс: логи производственного SCADA
В 2024 году к нам обратился крупный машиностроительный клиент. Представьте: 220 станков с ЧПУ, SCADA-системы по всей производственной сети, и всё это генерирует порядка 80 ГБ логов ежедневно! Их ключевая задача? Хранить эти данные три года для глубокого анализа и, что важно, моментального поиска аномалий. Что мы предложили? Архитектуру из трёх master-only нод на виртуалках (8 vCPU / 32 ГБ), трёх data_hot нод на физических серверах с NVMe — здесь как раз пригодились наши любимые Dell Xeon Platinum 8280 — и ещё двух data_cold нод на СХД с обычными HDD.
Мы справились всего за шесть рабочих дней: развернули кластер, настроили Filebeat на одиннадцати коллекторах, создали ingest-пайплайны специально для парсинга специфических SCADA-форматов и, конечно, внедрили ILM с ретенцией в три года. Вся эта работа обошлась клиенту в 280 000 рублей. А что сейчас? Спустя восемь месяцев этот кластер спокойно 'переваривает' 18 ТБ индексированных логов, и, что самое главное, поиск по всему этому объёму занимает всего 3–4 секунды. Отличный результат, не так ли?
Типичные грабли
- Split-brain. Одна или две master-ноды, без кворума. Всегда 3 master.
- Swap включён. ES начинает свопиться, производительность в пол.
bootstrap.memory_lock: true. - Слишком много шардов. 10 000 шардов на ноду — плохо. Консолидируйте, используйте ILM.
- mapping explosion. Динамический mapping создаёт поля на каждое новое имя в JSON — получаете тысячи полей. Используйте strict mapping.
- Забытый snapshot. Работает год, потом нужен — а SLM никто не настроил.
- Незащищённый ES. xpack.security выключена «для простоты» — через день в индексах находят тестовые базы с PII.
Развернём Elasticsearch под ваши данные
У нас на практике десятки боевых кластеров ES + Kibana. 15+ лет опыта, 8 серверов Dell Xeon Platinum 8280 с 40G Mellanox в дата-центре МТС Москва. Проектируем архитектуру под ваш объём логов, настраиваем ILM, снапшоты, мониторинг. Бесплатный аудит текущего кластера — за 2–3 часа.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
FAQ — Elasticsearch в продакшне
- Сколько нод минимум для продакшн-кластера?
- Три. Это минимум для отказоустойчивости кворума мастеров. Две ноды — split-brain неизбежен. Для малой нагрузки три ноды могут совмещать роли master/data, для средней и большой — выделите отдельные master-only.
- Какой heap размер ставить?
- Половина ОЗУ, но не больше 30–31 ГБ. Это граница сжатых указателей в JVM. Больший heap даёт хуже производительность. Вторая половина уходит файловому кэшу Lucene.
- Сколько шардов делать на индекс?
- Ориентир: 20–50 ГБ на шард. Для логового индекса 500 ГБ/день — 10 шардов. Слишком много шардов (тысячи) убивают кластер, слишком мало — нет параллелизма при запросах.
- Как бэкапить Elasticsearch?
- Только через snapshot API. Копировать data-директорию нельзя — файлы меняются. Регистрируйте репозиторий на S3/NFS/локальной папке и делайте snapshot через SLM (Snapshot Lifecycle Management) с ретенцией.
- Нужно ли включать security в 8.x?
- Да, с 8.0 security включён по умолчанию. Отключать в продакшне категорически нельзя — открытый ES уже сколько раз попадал в новости с утечками. Настройте TLS и пароли сразу.
