Реиндексирование
Как AACsearch собирает новую версию индекса и атомарно переключает алиас. Что делать, если реиндекс упал.
Реиндексирование
Реиндекс — это когда меняется схема индекса: новое поле, другой sort-ключ, другой ранжир по дефолту. На ежедневные обновления данных реиндексировать не нужно. Документы кладутся в буфер, буфер их флашит, существующий индекс продолжает обслуживать поиск.
Эта страница — про alias-swap-флоу: когда нужен, как ведёт себя, как восстанавливаться.
Модель: версионированная коллекция + алиас
Каждый логический индекс смотрит в физическую коллекцию через alias Typesense.
Alias: org_abc__products
Target: org_abc__products__v3 ← сейчас обслуживает поискПри реиндексе search-пакет:
- Читает текущий target и считает следующую версию (
v4). - Зовёт
createPhysicalCollection("org_abc__products__v4", fields). - Стримит документы из источника (PostgreSQL-запросы, pull коннектора или ваши данные) в
v4черезbulkUpsert. - Зовёт
swapAliasToVersion(alias, "v4")— атомарное переключение алиаса. - Опционально дропает старые версии (
v2,v1, …) с учётом retention.
Половинной коллекции не видит ни один запрос. Свап — одна операция Typesense, она целиком успешна или целиком неуспешна. При неудаче алиас остаётся на v3, а v4 уходит на очистку.
Когда реиндексировать
Реиндекс нужен, когда:
- Добавляете поле в схему.
- Удаляете поле.
- Меняете тип поля (
string→string[],int32→int64). - Меняете
default_sorting_field. - Меняете токенизер (
token_separators,symbols_to_index). - Меняете ранжир, зависящий от весов полей, зашитых в коллекцию.
Реиндекс не нужен, когда:
- Добавляете/обновляете документ (кладите в буфер).
- Добавляете синоним (синонимы — вне коллекции).
- Добавляете курацию (курация — query-time).
- Меняете scopes или origin allow-list ключа.
Запуск реиндекса
В дашборде:
- Project → Indexes → Reindex.
- Источник: From database (переотправить все активные документы из вашего источника в PostgreSQL) или From snapshot (использовать последний снапшот Typesense).
- Подтвердите. Реиндекс идёт в фоне. В дашборде прогресс-бар: документов в секунду + 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-буфера:
- Project → Indexes → Versions.
- Retention-буфер (по умолчанию — предыдущие 2 версии) показан с метками и количеством документов.
- Кнопка Promote напротив нужной версии — алиас атомарно переключается обратно.
После очистки retention-буфера откатиться уже нельзя — нужен реиндекс из источника.
Чтобы расширить retention под конкретный индекс — Settings → Versions to keep. Максимум на общем кластере — 5 версий. На выделенном кластере — больше.
Когда реиндекс упал
Падение оставляет вас в одном из двух состояний:
Состояние A: алиас всё ещё на старой версии
Это безопасный режим падения. Поиск не затронут. Новая (частичная) коллекция автоматически дропается через 24 часа или вручную из Versions → Discard.
Причины:
- Typesense закончилась память при сборке. Действие: тикет с размером индекса и сообщением об ошибке.
- В новой схеме поле отвергло реальные значения (
int32overflow,stringкороче min length). Действие: правьте схему или документ и повторите. - Источник иссяк раньше времени. Действие: убедитесь, что source-query возвращает ожидаемое число строк.
Состояние B: алиас переключился, но новая коллекция нездорова
Редкий случай: свап атомарный, но если шаг после свапа упал (например, не применился набор синонимов) — поиск может выдавать деградированные результаты.
Действие:
- Откатитесь к предыдущей версии (выше).
- Тикет с request id из строки
reindex_failed.
Реиндекс во время деплоя
Если в деплое есть изменение схемы — порядок:
- Деплойте код приложения с новой схемой.
- Запускайте реиндекс.
- Дождитесь
reindex_completed(опрос или дашборд). - Переключайте трафик на деплой.
Реиндекс до деплоя приложения с новыми полями — лишняя работа, если migration ещё изменится. Реиндекс после — создаёт окно, когда приложение ожидает поля, которых ещё нет. Порядок выше избегает обоих рисков.
Частые ошибки
- Реиндекс как фикс «застарелых» данных. Если документы устаревают — баг в ingest-пайплайне, а не в версии индекса. Проверьте статус буфера. Реиндекс маскирует симптом.
- Реиндексите слишком часто. Каждый реиндекс жжёт CPU/диск общего кластера. Чаще раза в неделю без изменения схемы — что-то не так.
- Promote старой версии «чтобы проверить откат». Promote — одна атомарная операция, но не бесплатная. Тестируйте откат в staging.
См. также
- Мониторинг — что значат жёлтый/красный значки
- Статус и инциденты — когда виноват кластер, а не вы
- Аудит — найти, кто и когда запускал реиндекс