AACsearch
Эксплуатация

Реиндексирование

Как AACsearch собирает новую версию индекса и атомарно переключает алиас. Что делать, если реиндекс упал.

Реиндексирование

Реиндекс — это когда меняется схема индекса: новое поле, другой sort-ключ, другой ранжир по дефолту. На ежедневные обновления данных реиндексировать не нужно. Документы кладутся в буфер, буфер их флашит, существующий индекс продолжает обслуживать поиск.

Эта страница — про alias-swap-флоу: когда нужен, как ведёт себя, как восстанавливаться.

Модель: версионированная коллекция + алиас

Каждый логический индекс смотрит в физическую коллекцию через alias Typesense.

Alias:    org_abc__products
Target:   org_abc__products__v3   ← сейчас обслуживает поиск

При реиндексе search-пакет:

  1. Читает текущий target и считает следующую версию (v4).
  2. Зовёт createPhysicalCollection("org_abc__products__v4", fields).
  3. Стримит документы из источника (PostgreSQL-запросы, pull коннектора или ваши данные) в v4 через bulkUpsert.
  4. Зовёт swapAliasToVersion(alias, "v4") — атомарное переключение алиаса.
  5. Опционально дропает старые версии (v2, v1, …) с учётом retention.

Половинной коллекции не видит ни один запрос. Свап — одна операция Typesense, она целиком успешна или целиком неуспешна. При неудаче алиас остаётся на v3, а v4 уходит на очистку.

Когда реиндексировать

Реиндекс нужен, когда:

  • Добавляете поле в схему.
  • Удаляете поле.
  • Меняете тип поля (stringstring[], int32int64).
  • Меняете default_sorting_field.
  • Меняете токенизер (token_separators, symbols_to_index).
  • Меняете ранжир, зависящий от весов полей, зашитых в коллекцию.

Реиндекс не нужен, когда:

  • Добавляете/обновляете документ (кладите в буфер).
  • Добавляете синоним (синонимы — вне коллекции).
  • Добавляете курацию (курация — query-time).
  • Меняете scopes или origin allow-list ключа.

Запуск реиндекса

В дашборде:

  1. Project → Indexes → Reindex.
  2. Источник: From database (переотправить все активные документы из вашего источника в PostgreSQL) или From snapshot (использовать последний снапшот Typesense).
  3. Подтвердите. Реиндекс идёт в фоне. В дашборде прогресс-бар: документов в секунду + ETA.

Программно:

POST /api/orpc/searchIndex.reindex
Content-Type: application/json
Authorization: Bearer ss_search_…  (scope: admin)

{ "indexId": "idx_…" }

Ответ — мгновенный, работа в очереди. Прогресс — через searchIndex.getReindexStatus.

Что происходит во время реиндекса

ПодсистемаПоведение
Поисковый трафикОбслуживается текущим target алиаса. Не затронут.
Ingest bufferНовые записи продолжают идти в очередь. После создания новой версии они флашатся в новую — не теряются.
Synonyms, curationsАвтоматически переприменяются к новой версии.
API-ключиБез изменений. Те же ключи против того же алиаса.
Audit logПишет action: reindex_started, потом reindex_completed или reindex_failed.

Текущий алиас обслуживает поиск до самого свапа. Если отменить посреди — частичная коллекция чистится, трафик идёт без перерыва.

Sizing и время

Скорость реиндекса определяется bulk import Typesense и источником данных. Грубые оценки на общем кластере:

ДокументовТипичное время
< 100 тыс< 1 мин
100 тыс – 1 млн1 – 10 мин
1 млн – 10 млн10 мин – 2 ч
> 10 млнСначала пишите саппорту

Если вы у верхней границы, до запуска в рабочие часы напишите. Мы прогреем целевую коллекцию и дадим выделенного воркера.

Откат

Откатиться к предыдущей версии можно в любой момент до её удаления из retention-буфера:

  1. Project → Indexes → Versions.
  2. Retention-буфер (по умолчанию — предыдущие 2 версии) показан с метками и количеством документов.
  3. Кнопка Promote напротив нужной версии — алиас атомарно переключается обратно.

После очистки retention-буфера откатиться уже нельзя — нужен реиндекс из источника.

Чтобы расширить retention под конкретный индекс — Settings → Versions to keep. Максимум на общем кластере — 5 версий. На выделенном кластере — больше.

Когда реиндекс упал

Падение оставляет вас в одном из двух состояний:

Состояние A: алиас всё ещё на старой версии

Это безопасный режим падения. Поиск не затронут. Новая (частичная) коллекция автоматически дропается через 24 часа или вручную из Versions → Discard.

Причины:

  • Typesense закончилась память при сборке. Действие: тикет с размером индекса и сообщением об ошибке.
  • В новой схеме поле отвергло реальные значения (int32 overflow, string короче min length). Действие: правьте схему или документ и повторите.
  • Источник иссяк раньше времени. Действие: убедитесь, что source-query возвращает ожидаемое число строк.

Состояние B: алиас переключился, но новая коллекция нездорова

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

Действие:

  1. Откатитесь к предыдущей версии (выше).
  2. Тикет с request id из строки reindex_failed.

Реиндекс во время деплоя

Если в деплое есть изменение схемы — порядок:

  1. Деплойте код приложения с новой схемой.
  2. Запускайте реиндекс.
  3. Дождитесь reindex_completed (опрос или дашборд).
  4. Переключайте трафик на деплой.

Реиндекс до деплоя приложения с новыми полями — лишняя работа, если migration ещё изменится. Реиндекс после — создаёт окно, когда приложение ожидает поля, которых ещё нет. Порядок выше избегает обоих рисков.

Частые ошибки

  • Реиндекс как фикс «застарелых» данных. Если документы устаревают — баг в ingest-пайплайне, а не в версии индекса. Проверьте статус буфера. Реиндекс маскирует симптом.
  • Реиндексите слишком часто. Каждый реиндекс жжёт CPU/диск общего кластера. Чаще раза в неделю без изменения схемы — что-то не так.
  • Promote старой версии «чтобы проверить откат». Promote — одна атомарная операция, но не бесплатная. Тестируйте откат в staging.

См. также

On this page