Гигабайт исходных документов и гигабайт поискового индекса — разные вещи, хотя названы они почти одинаково. Таблица в базе на 20 ГБ может превратиться в индекс на 12 ГБ, а может в 45 ГБ, и разница не случайна: она складывается из того, как вы описали поля, какие анализаторы подключили, сколько копий держите и что происходит в фоне. Поэтому вопрос «влезет ли наш индекс на свой сервер» нельзя решить, посмотрев на размер выгрузки. Его решают оценкой самого индекса, проверкой совместимости и репетицией восстановления.

Ниже разобрано, из чего складывается занимаемое место, чем переносимость данных отличается от переносимости функций, как шарды и реплики влияют на диск, почему восстановленный индекс надо допрашивать настоящими запросами и как сопоставить желаемую конфигурацию с памятью и диском VPS.

Из чего на самом деле состоит индекс

Индекс Elasticsearch — это не копия ваших документов с оглавлением. Это несколько слоёв, каждый со своей ценой.

  • Исходный документ. Поисковая система хранит оригинальный JSON, чтобы вернуть его в выдаче. Если в документах много крупных полей, которые вам нужны только для поиска, а не для показа, часть этого хранения можно считать избыточной — но решение об изменении схемы принимается отдельно и до миграции, а не во время неё.
  • Структуры для поиска. Текстовые поля разбираются анализатором на термины, и для них строятся обратные индексы. Чем богаче анализ (морфология, n-граммы, синонимы), тем больше терминов и тем тяжелее структура. Автокомплит на n-граммах способен раздуть поле многократно.
  • Структуры для сортировки и агрегаций. Поля, по которым вы группируете и сортируете, хранятся в колоночном виде. Поле, которое вы никогда не агрегируете, но оставили в стандартном маппинге, всё равно может платить за эту возможность.
  • Векторы и прочие специальные поля. Если в индексе есть векторные поля, они занимают место и ещё требуют памяти при поиске. Это отдельная статья расходов, и считать её надо по реальной размерности и количеству документов.

Отсюда первый практический вывод: смотрите не на размер источника данных, а на фактический размер индекса в вашем текущем кластере и на его mapping. Размер на диске по каждому индексу показывает команда GET _cat/indices?v&bytes=gb, а подробности по полям и сегментам — соответствующие API статистики. Это стандартные инструменты Elasticsearch, их стоит прогнать до любых выводов и сохранить результат: он станет точкой отсчёта для сравнения после восстановления.

Mapping и анализаторы как часть данных

При восстановлении из snapshot mapping и настройки индекса приезжают вместе с ним, и это хорошо: схема не потеряется. Но есть тонкость, которую легко упустить. Если анализатор опирается на внешний ресурс — файл синонимов, словарь, плагин — то сам индекс переедет, а вот зависимость придётся обеспечить на новом сервере. Индекс без нужного плагина либо не откроется, либо будет вести себя иначе, чем вы привыкли. Поэтому в опись переезда входят не только индексы, но и всё, что их анализаторы вызывают.

Полезно выписать для каждого индекса короткую карточку: какие анализаторы и нормализаторы использованы, есть ли пользовательские словари и файлы, какие поля участвуют в сортировке и агрегациях, какие шаблоны индексов и алиасы к нему привязаны. Именно эта карточка потом подскажет, что проверять после восстановления.

Snapshot переносит данные, но не гарантирует, что всё остальное заработает

Основной штатный способ перенести индекс — snapshot and restore. Снимок хранится в зарегистрированном репозитории вне кластера, и его можно восстановить в другом кластере. Здесь важно различать два вопроса: «можно ли восстановить индекс» и «заработает ли всё, что вокруг него».

По документации Elasticsearch по snapshot and restore, версии snapshot, целевого кластера и восстанавливаемых индексов должны быть совместимы, а восстановить snapshot в более старую версию Elasticsearch нельзя. Практический смысл прост: целевой сервер не может быть старше источника. Если вы разворачиваете собственный кластер, версию выбирают не по привычке и не «самую свежую на всякий случай», а исходя из версии, на которой живёт ваш индекс сейчас. Точный номер вы смотрите у себя в консоли развёртывания или запросом к корню кластера, а затем сверяете с таблицей совместимости в документации той версии, которую планируете ставить.

Та же страница предупреждает о втором ограничении: совместимость восстановления индекса не гарантирует совместимости всех приложений и feature states, которые используют эти данные. Другими словами, индекс восстановится, а надстройки над ним — отдельная история. Если поверх данных работают дашборды, правила оповещений, пайплайны приёма или другие компоненты, их нужно инвентаризировать отдельно: часть из них хранится как служебные данные, часть настраивается снаружи, и поведение зависит от версии и лицензии.

Функции: что переедет, а что придётся пересмотреть

Разделите опись на три корзины. В первую попадает собственно поиск: индексы, mapping, анализаторы, запросы. Это то, ради чего вы переезжаете, и оно переносится через snapshot при совместимых версиях. Во вторую — окружение: пользователи и роли, ключи API, сетевые правила, алерты, мониторинг. Их нужно создать на новом месте заново, потому что управляемая инфраструктура Elastic Cloud, лицензия и секреты платформы не переносятся автоматически вместе с индексами. В третью — функции, которые могут зависеть от редакции и лицензии.

С третьей корзиной важно не гадать. Какие именно возможности доступны в какой редакции и какой лицензии при самостоятельном развёртывании, определяется страницей подписок и документацией выбранной версии, и этот список меняется. Правильный порядок такой: выписать функции, которые ваше приложение реально вызывает (не те, что включены в консоли, а те, что используются в коде и запросах), и по каждой найти в документации выбранной версии условие доступности. Если для какой-то функции условие вас не устраивает, это повод заранее подумать об альтернативе: упростить запрос, заменить механизм или рассмотреть другой движок. Для такого случая у нас есть материал про установку и настройку OpenSearch на VPS, но учтите: это отдельный продукт, и совместимость с вашим индексом и клиентами пришлось бы проверять так же отдельно, а не считать само собой разумеющейся.

Отдельно о слове «копирование». Скопировать каталог данных работающего Elasticsearch — не то же самое, что сделать snapshot. Файлы живого узла в момент копирования могут быть в неконсистентном состоянии, и штатным способом переноса это не является. Для переезда используйте именно механизм snapshot, а не копирование дисков.

Диск: учебный расчёт с запасом на восстановление

Теперь цифры. Возьмём условный пример, не отражающий чьи-либо реальные измерения: пусть в текущем кластере основной индекс занимает 60 ГБ при одной первичной копии данных и одной реплике. Важно понять, что же именно в этих 60 ГБ.

Если показатель размера индекса включает и первичные шарды, и реплики, то данных самих по себе — около 30 ГБ. Если же 60 ГБ — это только первичные шарды (а реплики сверху дадут ещё столько же), картина другая. Поэтому первый шаг — выяснить, что именно показывает ваша команда: в выводе _cat/indices есть отдельные столбцы для размера первичных данных и общего размера. Допустим, мы выяснили: первичные данные — 60 ГБ.

Учебный расчёт диска для одного узла (числа условные)
СтатьяДопущениеГБ
Первичные данные индексаиз статистики текущего кластера60
Реплики на одном узле0: на единственном сервере реплику некуда размещать0
Запас под слияние сегментов и ростпо 30% от данных, условно18
Snapshot-файлы, лежащие на том же сервере на время восстановленияпорядка размера данных, условно60
Система, логи, сам Elasticsearchусловно10
Итого на время переезда148

Обратите внимание на строку про snapshot. Если репозиторий лежит на самом сервере, то в момент восстановления диск хранит и снимок, и восстановленный индекс одновременно — места нужно примерно вдвое больше, чем для работы в штатном режиме. Это одна из частых причин, почему «данных вроде бы 60 ГБ, а восстановление упёрлось в диск». Если репозиторий вынести на отдельное хранилище, строка из расчёта уходит, но тогда нужно подумать о пропускной способности канала и о том, как репозиторий будет подключён.

После успешной проверки снимок можно перенести или удалить, и постоянная потребность в диске в нашем примере упадёт примерно до 88 ГБ плюс то, что вы заложите на рост. Этот расчёт полезен не точными числами, а структурой: данные, запас на фоновые операции, место под восстановление, система. Подставьте свои цифры из статистики и посмотрите, что получилось.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.

АРЕНДОВАТЬ СЕРВЕР

Шарды, реплики и фоновые операции едят место незаметно

Число шардов и реплик — главный рычаг, который меняет аппетит индекса к диску и памяти. Каждая реплика — это полная копия первичного шарда, так что индекс с одной репликой занимает на дисках кластера вдвое больше, чем без неё. В облачном кластере с несколькими узлами реплики дают отказоустойчивость и распределяют чтение. На одном VPS это работает иначе: копия, лежащая на том же диске того же сервера, не защищает ни от потери диска, ни от падения сервера. Поэтому в одноузловой конфигурации реплики обычно просто не имеют смысла, а лишний расход места и ресурсов лучше убрать. Но это решение нужно принять осознанно: вы теряете избыточность и должны компенсировать её регулярными snapshot во внешний репозиторий.

Если вы собираетесь держать несколько VPS в одном кластере, помните: разные виртуальные серверы сами по себе не дают гарантий размещения на разном оборудовании, и рассчитывать на отказоустойчивость только из-за числа узлов не стоит без отдельной проверки.

Теперь о количестве шардов. Каждый шард — это отдельная структура Lucene с собственными накладными расходами на память и файловые дескрипторы. Много мелких шардов на маленьком сервере — классическая ловушка: данных немного, а узел тратит память на учёт сотен шардов. Если в облаке у вас стояла схема с большим числом шардов под масштабирование, то при переезде на один узел её стоит пересмотреть. Менять число первичных шардов уже созданного индекса напрямую нельзя, но можно пересоздать индекс или воспользоваться механизмами сжатия или перераспределения, предусмотренными документацией вашей версии. Это план для отдельного этапа после того, как базовое восстановление доказало свою работоспособность.

Фоновые операции

Диск расходуется не только на данные. Elasticsearch постоянно сливает сегменты: пока идёт слияние, старые и новые сегменты существуют одновременно, и пик потребления места превышает итоговый размер. Индексы с интенсивными обновлениями и удалениями особенно чувствительны: удалённые документы физически уходят только после слияния, и до тех пор индекс занимает больше, чем «живые» данные. Это и есть причина запаса «на слияния и рост» в нашем расчёте.

Кроме того, у Elasticsearch есть пороги заполнения диска (watermarks): при приближении к ним узел начинает ограничивать размещение шардов и, при высоком заполнении, блокирует запись в индексы. Практический вывод: диск, заполненный на 90% «данными», — это уже не рабочая конфигурация, даже если формально место ещё есть. Точные значения порогов и поведение смотрите в документации выбранной версии, а при планировании держите заметную долю свободного места.

Если у вас есть данные с естественным сроком жизни — журналы, события, метрики — задумайтесь, нужно ли переносить всё. Иногда разумнее перенести только актуальный период, а исторические индексы оставить в архивном snapshot. Такое решение уменьшает и объём восстановления, и требования к диску нового сервера.

Репетиция на тестовом VPS: восстановить и допросить

Сделать snapshot и увидеть слово SUCCESS — этого мало. Успешное восстановление означает только то, что файлы разложились по местам. Нужно убедиться, что индекс отвечает так же, как отвечал раньше. Для этого и нужен тестовый сервер: подняйте на нём ту же или подходящую по документации версию, подключите репозиторий, восстановите нужные индексы и проведите проверку до того, как трогать боевое приложение.

Если вы планируете для репетиции арендовать VPS, удобно, что серверы MAATRIX с NVMe, процессорами AMD EPYC и root-доступом создаются автоматически вскоре после оплаты: тестовую машину можно получить быстро, прогнать на ней восстановление и по результатам решить, какой тариф нужен, или отказаться от переезда, не потратив недели на подготовку. Локации в публичном предложении указаны UK, US, RU и FR, а оплата возможна картой РФ и через СБП; доступность образов и точные параметры уточняйте в форме заказа.

Что именно проверять

Сверка начинается с простого: количество документов в каждом индексе до и после, размер на диске, число шардов, алиасы, шаблоны, настройки. Расхождение в числе документов — сигнал остановиться и разбираться. Расхождение в размере на диске само по себе не ошибка (сегменты могут быть уложены иначе), но порядок величин должен совпадать.

Дальше — самое важное: прогнать реальные запросы. Не «поиск работает», а конкретный набор:

  • 10–30 самых частых запросов из логов приложения с реальными фразами пользователей, включая опечатки и редкие слова;
  • запросы с фильтрами, сортировкой и агрегациями, которые строят страницы каталога или отчёты;
  • запросы, которые зависят от анализаторов: морфология русского языка, синонимы, автодополнение;
  • «трудные» запросы: глубокая пагинация, широкие подстановки, тяжёлые агрегации;
  • запросы, использующие функции, про которые в описи было неясно, доступны ли они в вашей конфигурации.

Для каждого из них сохраните эталон из текущего кластера: топ выдачи, число найденных документов, значения агрегаций, время ответа. После восстановления сравните. Совпадение числа найденных и состава первых позиций — хороший признак. Отличия порядка выдачи для близких по релевантности документов могут возникать из-за различий в распределении данных по шардам и статистике, поэтому сравнивайте осмысленно: важны не побитовые совпадения, а то, что нужные документы находятся и выдача годна для вашего сценария. Если что-то пропало или ведёт себя странно, вернитесь к карточке индекса: чаще всего причина в анализаторе, словаре или функции, которая не была учтена.

Отдельно прогоните приложение целиком: подключите тестовое окружение приложения к новому серверу, проверьте аутентификацию, клиентскую библиотеку и формат запросов. Сам индекс может быть в порядке, а клиент — рассчитывать на особенности облачной точки входа. Это ровно тот случай, о котором предупреждает документация: совместимость восстановления индекса не означает совместимости всего, что на нём построено.

Наконец, замерьте поведение под нагрузкой. Ответ на одном запросе — это одно, а десятки параллельных запросов при фоновой индексации — другое. Нагрузочный прогон на тестовом VPS даст реальные цифры вместо предположений; без него любое утверждение о том, что «этот тариф потянет», остаётся догадкой.

Желаемая конфигурация против доступной памяти и диска

Когда есть оценка диска и результаты репетиции, можно сопоставлять с тарифами. В публичном каталоге MAATRIX указаны такие ресурсы: Ba — 1 vCPU, 2 ГБ RAM, 40 ГБ NVMe; Uab — 2 vCPU, 4 ГБ, 80 ГБ; Heka — 4 vCPU, 8 ГБ, 160 ГБ; Maat — 8 vCPU, 16 ГБ, 240 ГБ; Djed — 16 vCPU, 32 ГБ, 320 ГБ. Это описание ресурсов, а не обещание ёмкости: сколько запросов и какой индекс выдержит конкретная конфигурация, показывает только замер.

Сопоставление идёт по двум осям — диск и память — и они ведут себя по-разному.

Диск — ограничение жёсткое и считается арифметикой. В нашем учебном примере на время восстановления нужно около 148 ГБ, а в штатном режиме — около 88 ГБ плюс рост. Значит, в учебном случае под восстановление на самом сервере подходит план с диском ощутимо больше 148 ГБ, а при вынесенном репозитории рабочий объём требует запаса сверх 88 ГБ. Тариф на 80 ГБ в этом примере не подойдёт по диску вообще, как бы хорошо ни обстояли дела с памятью. Меняйте условные числа на свои и проверяйте так же.

Память — ограничение мягче и зависит от характера нагрузки. Elasticsearch использует кучу JVM и, кроме неё, файловый кэш операционной системы: быстрые поиски во многом держатся на том, что горячие части индекса лежат в page cache. Если памяти хватает только на кучу и систему, а индекс почти целиком читается с диска, задержки вырастут, хотя NVMe смягчает эту проблему. Рекомендации по размеру кучи и запасу под кэш берите из документации выбранной версии, а не из чужих правил на форумах. Тяжёлые агрегации, векторный поиск, большое число шардов и параллельная индексация увеличивают аппетит к памяти, и это нужно проверять нагрузочным тестом на тестовой машине.

Есть и компромиссы, которые стоит решить заранее:

  • Реплики или экономия. Одноузловая конфигурация без реплик дешевле по диску, но восстановление после потери сервера целиком зависит от внешнего snapshot. Какая частота снимков вас устраивает — вопрос к допустимой потере данных, а не к технике.
  • Один узел или несколько. Несколько узлов дают запас по памяти и диску суммарно, но добавляют сетевое взаимодействие, настройку кластера и новые виды отказов. Для небольшого индекса один узел с хорошим внешним snapshot часто проще в обращении, а для большого придётся считать иначе.
  • Что переносить. Исторические данные, которые читают редко, можно оставить в архивном snapshot, и тогда рабочая конфигурация станет заметно скромнее.
  • Какие функции сохранить. Если без функции, чьи условия доступности вас не устраивают, не обойтись, пересматривается не тариф, а сама схема переезда.

Эту сводку удобно оформить в виде короткой таблицы по каждому индексу: размер первичных данных, число шардов в целевой схеме, требуемый диск с запасом, критичные запросы и результат их проверки. Такой документ превращает разговор «кажется, должно влезть» в проверяемое решение.

Условие, при котором переезд состоится

Переезд из Elastic Cloud на собственный сервер оправдан не тогда, когда snapshot создан и файлы лежат на новом диске, а тогда, когда восстановленный индекс отвечает на нужные вам запросы в выбранной конфигурации: с той версией, теми анализаторами, тем числом шардов и тем объёмом памяти и диска, которые вы реально будете держать. Пока этот тест не пройден на тестовом VPS с вашим набором запросов, любые разговоры о сроках и тарифах — предварительные. Как только он пройден, остальное становится обычной инженерной работой: окружение, доступы, расписание snapshot и аккуратное переключение приложения.