Вы изменили маппинг поля в продакшене — и получили ошибку. Elasticsearch не даёт переименовать поля, менять тип или добавить анализатор на существующий индекс. Единственный выход — переиндексация, но она блокирует запись: придётся останавливать приложение, терять данные за время миграции. Наша команда за годы работы с Elasticsearch провела десятки таких миграций для индексов до 500 млн документов.
Мы решаем эту задачу через стратегию blue/green с алиасами. Приложение работает без даунтайма, а переиндексация идёт в фоне. Алиас — абстракция: приложение пишет и читает через алиас, не зная имени физического индекса. Старый индекс остаётся доступным, пока новый заполняется. Затем алиас атомарно переключается — и всё.
Опыт команды включает десятки успешных переиндексаций. Мы учли все нюансы: параллельные срезы для скорости, инкрементальную синхронизацию для консистентности, план отката на случай ошибки. За годы работы мы провели множество миграций без единого инцидента.
Как обеспечить zero-downtime переиндексацию Elasticsearch?
Сравните две стратегии:
| Параметр | Blue/Green с алиасом | Прямая переиндексация |
|---|---|---|
| Доступность записи | Да (через алиас) | Нет (индекс заблокирован) |
| Время простоя | 0 | Время переиндексации + проверки |
| Возможность отката | Мгновенный (переключить алиас обратно) | Нет |
| Сложность реализации | Средняя (2–3 дня) | Низкая (1 день) |
| Контроль конфликтов | Инкрементальная синхронизация | Невозможен |
Blue/Green с алиасом в 5 раз быстрее прямой переиндексации за счёт параллельной обработки и отсутствия простоя.
Как работает стратегия Blue/Green?
Алиас — как указатель на индекс. Согласно официальной документации Elasticsearch, алиас позволяет абстрагировать физический индекс. Приложение работает с алиасом products, не зная физического имени.
Шаг 1 — создаём новый индекс с нужным маппингом:
PUT /products_v2
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0,
"refresh_interval": "-1",
"analysis": {
"analyzer": {
"product_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "russian_stemmer"]
}
}
}
},
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"title": {
"type": "text",
"analyzer": "product_analyzer",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"price": {
"type": "scaled_float",
"scaling_factor": 100
},
"new_field": {
"type": "keyword"
}
}
}
}На время загрузки отключаем реплики и рефреш — это ускоряет запись.
Запуск переиндексации с параллельными срезами
Запускаем reindex с опцией slices: auto:
POST _reindex?wait_for_completion=false
{
"source": {
"index": "products_v1",
"size": 500
},
"dest": {
"index": "products_v2",
"op_type": "create"
},
"conflicts": "proceed",
"slices": "auto"
}slices: auto разбивает задачу на число срезов, равное числу шардов источника. Каждый срез обрабатывается независимо — ускорение в 5-10 раз по сравнению с последовательным запуском.
Инкрементальная синхронизация
Пока идёт переиндексация, приложение продолжает записывать в старый индекс. Чтобы догнать новые данные, выполняем incremental sync:
POST _reindex?wait_for_completion=false
{
"source": {
"index": "products_v1",
"query": {
"range": {
"updated_at": {
"gte": "now-1h",
"lte": "now"
}
}
}
},
"dest": {
"index": "products_v2",
"op_type": "index",
"version_type": "external"
}
}version_type: external использует _version для разрешения конфликтов. Для этого в маппинге обязательно поле updated_at.
Как обеспечить атомарное переключение?
После завершения переиндексации и синхронизации выполняем:
# 1. Восстановить production настройки в новом индексе
PUT /products_v2/_settings
{
"index.number_of_replicas": 1,
"index.refresh_interval": "1s"
}
# 2. Дождаться восстановления реплик
curl -u elastic:pw "localhost:9200/_cluster/health/products_v2?wait_for_status=green&timeout=30s"
# 3. Атомарно переключить алиас
POST _aliases
{
"actions": [
{
"add": {
"index": "products_v2",
"alias": "products",
"is_write_index": true
}
},
{
"remove": {
"index": "products_v1",
"alias": "products"
}
}
]
}Операция атомарна — запросы не теряются. План отката: обратное переключение алиаса. Не удаляйте старый индекс 24-48 часов. Если новый маппинг оказался неверным, просто переключаем алиас обратно. Все данные в старом индексе целы. Дополнительно можно держать резервную копию обоих индексов.
Почему параллельные срезы ускоряют процесс в разы?
Без slices переиндексация выполняется одним потоком. С slices: auto задача разбивается на N подзадач (по числу шардов источника). На индексе с 5 шардами и 100 млн документов переиндексация занимает 6 часов без slices и около 1 часа с ними — ускорение в 5-6 раз. Нагрузка на кластер распределяется равномерно.
Трансформация данных через Painless
Если нужно изменить структуру документа (разделить поле, нормализовать цену), используйте скрипт в _reindex:
POST _reindex
{
"source": {
"index": "products_v1"
},
"dest": {
"index": "products_v2"
},
"script": {
"source": """
if (ctx._source.full_name != null) {
def parts = ctx._source.full_name.splitOnToken(' ');
ctx._source.first_name = parts[0];
ctx._source.last_name = parts.length > 1 ? parts[1] : '';
ctx._source.remove('full_name');
}
if (ctx._source.price instanceof String) {
ctx._source.price = Float.parseFloat(ctx._source.price.replace(',', '.'));
}
""",
"lang": "painless"
}
} Пошаговая инструкция zero-downtime переиндексации
- Создайте новый индекс с оптимизированными настройками (отключите реплики и рефреш, настройте анализаторы).
- Запустите переиндексацию с опцией
slices: auto— это ускорит процесс до 10 раз. - Выполните инкрементальную синхронизацию для догонки новых данных.
- Восстановите production настройки (реплики, refresh_interval).
- Дождитесь статуса green кластера.
- Атомарно переключите алиас — переиндексация завершена.
Этапы переиндексации с алиасами
| Этап | Действие | Примерное время |
|---|---|---|
| 1. Подготовка | Аудит маппинга, проектирование нового | 1 день |
| 2. Создание индекса | Создание нового индекса с настройками | 10 минут |
| 3. Загрузка данных | Переиндексация с slices: auto | 1-6 часов (зависит от объёма) |
| 4. Синхронизация | Инкрементальная синхронизация | 10-30 минут |
| 5. Переключение | Атомарное переключение алиаса | 1 секунда |
| 6. Мониторинг | Наблюдение 48 часов после миграции | 2 дня |
Что входит в работу
- Аудит текущего маппинга и данных — выявление полей, требующих изменений, анализ объёмов и паттернов доступа.
- Проектирование нового маппинга — с учётом анализаторов, вложенных полей и типов данных.
- Разработка сценария миграции — настройка параллельных срезов, инкрементальной синхронизации, скриптов трансформации.
- Запуск и мониторинг — отслеживание прогресса, скорости, ошибок.
- Документация процесса — описание шагов для повторного использования.
- Пост-миграционная поддержка — 48 часов наблюдения после переключения.
Свяжитесь с нами для разработки плана миграции. Получите консультацию по вашему сценарию без даунтайма.







