К ленте · Россия

РоссияСтатьяМодели

Что бэкапить в ИИ-приложении: модель, документы, индексы или историю диалогов?

Содержание
  1. 1. Из чего состоит ИИ-помощник и почему бэкапа одной базы мало
  2. 2. Какие данные ИИ-помощника нужно сохранять в бэкапе, а какие можно восстановить заново
  3. 3. Когда выгоднее: пересобрать данные VS восстановить из копии
  4. 4. Как организовать бэкапы в S3, PostgreSQL и Kubernetes
  5. Что обсудим в следующей части

Привет, Хабр! На связи Михаил Витко, менеджер PaaS-продуктов Рег.облака. Представим ситуацию. После восстановления ИИ-помощник принимает запросы и отвечает без ошибок. Но на вопрос о сроке возврата товара называет 14 дней вместо 30: база уже знает о новой редакции регламента, а поиск работает по старому индексу. Проверка доступности сервиса такую поломку не обнаружит.

В статье подробно разберем, как резервировать RAG-помощника по корпоративным документам и восстанавливать его части в согласованном состоянии. Тема обширная, поэтому мы разделили материал на две части. В первой поговорим о том, какие данные нужно сохранять, что можно пересоздать после сбоя и как организовать резервное копирование в S3, PostgreSQL и Kubernetes. А во второй обсудим, как восстановить приложение без рассогласования данных и проверить, что оно корректно работает после сбоя.

Навигация по тексту:

  • Архитектура ИИ-помощника
  • Данные и бэкапы
  • Восстановление или пересборка
  • Практика: S3, PostgreSQL, Kubernetes

1. Из чего состоит ИИ-помощник и почему бэкапа одной базы мало

За пример возьмем архитектуру на сервисах Рег.облака: исходники лежат в S3, DBaaS PostgreSQL хранит версии документов, прикладные права и историю диалогов, а API и обработчики работают в KaaS. Qdrant разворачиваем самостоятельно в этом же Kubernetes как StatefulSet с PVC и Persistent Volume. Это компонент приложения, за его данные и штатные снимки отвечает команда приложения. Генерацию ответов выполняет внешняя LLM по API; эмбеддинги создает отдельная модель.

При загрузке документа обработчик сохраняет исходный файл, извлекает текст, делит его на фрагменты и рассчитывает эмбеддинги. Когда пользователь задает вопрос, приложение находит разрешенные ему фрагменты и передает их языковой модели. Этот способ добавления источников в контекст называется RAG — retrieval-augmented generation.

Компоненты обновляются независимо. Файл уже может появиться в S3, хотя обработчик ещё не записал все векторы. База может хранить новую редакцию документа, пока индекс содержит предыдущую. Если сохранить только PostgreSQL, после отказа останутся ссылки на файлы и фрагменты, которых больше нет.

Единица восстановления в этом случае — согласованный набор данных приложения. В него входят конкретные версии документов, их метаданные, состояние индекса и версии кода и моделей, которые умеют с ними работать. Бэкап каждого хранилища нужен, но он не задает согласованность между ними.

На схеме показаны рабочие потоки и точки резервирования. Резервный контур размещен вне исходной площадки, с отдельными доступами. Он содержит экспорт приложения, не только штатные бэкапы облачных сервисов. Сервис политик и его журнал тоже не зависят от рабочего кластера.

Рисунок 1. Сплошные линии — рабочие потоки, пунктир — резервирование. При потере рабочего контура должны остаться доступны хранилище копий, код, образы, ключи расшифрования и сервис политик. Доступность внешней LLM проверяется отдельно

2. Какие данные ИИ-помощника нужно сохранять в бэкапе, а какие можно восстановить заново

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

Эмбеддинги и индекс — разные уровни. Сохраненные векторы позволяют заново построить поисковую структуру без повторного обращения к модели. Если остались только PDF, придется снова выполнить извлечение текста, разбиение и векторизацию.

Для приложения с внешней LLM скопировать модель провайдера обычно нельзя. Сохраняем идентификатор используемой модели, параметры запросов, промпты и тесты. Если провайдер уберет эту версию, даже полный бэкап приложения не вернет прежнее поведение. Нужен заранее проверенный вариант замены.

Для эмбеддингов важно сохранить саму модель или гарантировать доступ к точной версии. Новая модель с той же размерностью может создавать другое векторное пространство. Старые векторы документов и новые векторы запросов тогда нельзя считать совместимыми только потому, что у них одинаковая длина.

Историю диалогов резервируем с устойчивыми conversation_id, message_id, порядком сообщений, ролями, содержимым, организацией и ссылками на вложения. При восстановлении сравниваем сами сообщения и их последовательность, а не только количество строк. Подтвержденные пользователю сообщения после точки копии будут потеряны, если их не сохранили WAL или отдельный журнал. Для переписки нужен свой RPO.

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

3. Когда выгоднее: пересобрать данные VS восстановить из копии

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

Допустим, в корпусе миллион фрагментов, а на тесте тот же конвейер обрабатывает 100 фрагментов в секунду. Только эта часть пересборки займет около 2 часов 47 минут. Развертывание инфраструктуры и проверка поиска потребуют дополнительного времени. Это расчетный пример, а не результат замера конкретной платформы.

Если в каждом фрагменте в среднем 500 токенов, повторная векторизация затронет 500 миллионов токенов. При тарифе p рублей за миллион токенов стоимость одних эмбеддингов составит 500 × p. Отдельно считаем вычисления, чтение объектов, сетевой трафик и время инженера. Ограничения API и повторные попытки также влияют на срок восстановления.

Теперь сравним с копией. Передача снимка размером 100 ГиБ при фактической скорости 100 МиБ/с займет примерно 17 минут. Это только передача: затем снимок нужно загрузить в движок, дождаться готовности индекса и выполнить проверки. Скорость следует измерять на выбранной площадке, а не брать из пропускной способности сетевого интерфейса.

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

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

4. Как организовать бэкапы в S3, PostgreSQL и Kubernetes

Для этого примера берем KaaS под API, обработчики и Qdrant, DBaaS PostgreSQL под прикладное состояние и S3 Рег.облака под документы. Внешний резервный контур из рисунка 1 собираем отдельно. Переживание отказа всего рабочего контура не следует из размещения второго бакета в той же инфраструктуре.

S3

Для файлов считаем SHA-256 от содержимого и записываем его в каталог восстановления. Не подменяем его значением ETag: например, в Amazon S3 ETag объекта, загруженного частями, не является обычным MD5 всего файла.

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

В выбранной схеме защиту копий строим на отдельном резервном контуре и независимых правах, без зависимости от нативных Versioning и Object Lock рабочего S3. Если резервное хранилище поддерживает Object Lock, настраиваем режим и срок удержания: в Amazon S3 блокировка защищает конкретную версию и не запрещает новые версии или маркеры удаления. Поддержку этого механизма подтверждают для выбранного хранилища, а прикладное именование редакций само по себе не является WORM-защитой.

Срок хранения распространяется на весь набор восстановления. Дамп базы бесполезен, если lifecycle-политика уже удалила версии файлов, на которые он ссылается. Ключи расшифрования тоже должны оставаться доступными в течение этого срока.

DBaaS PostgreSQL

В инструкции Рег.облака описаны автоматические ежедневные копии кластеров БД, хранение за последние 7 дней и восстановление в новый кластер той же конфигурации. Для остановленного кластера новые копии не создаются. Новый кластер позволяет проверить результат до переключения приложения; далее обновляем параметры подключения и секреты.

В техническом описании платформы также указаны бэкапы PostgreSQL в S3 через barman-cloud и CloudNativePG с поддержкой PITR. Это механизм базы данных: он не восстанавливает автоматически корпус S3 и индекс Qdrant на ту же логическую версию. Штатные копии дополняем собственным экспортом согласованного набора во внешний резервный контур.

Для небольшого приложения можно начать с логического дампа. pg_dump создает согласованный снимок одной базы, даже если в нее продолжают писать. Он не согласует этот снимок с S3 и Qdrant.

Пример экспорта и восстановления в заранее созданную пустую тестовую базу:

pg_dump --dbname=service=rag_source \ --format=custom --file=postgres.dumppg_restore --dbname=service=rag_restore \ --exit-on-error --no-owner --no-privileges \ postgres.dump

Здесь rag_source и rag_restore — профили подключения libpq. Пароли не записываем в команды или статью. При восстановлении намеренно не переносим владельцев и SQL-привилегии: роли и минимальные разрешения создаем отдельным проверенным сценарием. Прикладные права пользователей, хранящиеся в таблицах, дамп при этом содержит.

Если нужен меньший RPO, рассматриваем физические базовые копии и непрерывное архивирование WAL либо соответствующий механизм управляемой БД. Для PITR нужны подходящая базовая копия и непрерывная цепочка журналов до точки восстановления; одного логического дампа недостаточно.

В плане восстановления фиксируем фактически доступное окно PITR и способ задания точки для конкретного кластера. Наличие PITR в архитектуре не заменяет проверку клиентского сценария. Для независимого восстановления сохраняем экспорт, версии сервера и клиента, расширения, роли и настройки. Файлы серверной конфигурации не восстанавливаются через WAL.

KaaS Рег.облака и Qdrant на Persistent Volume

В репозитории храним манифесты или Helm chart, значения конфигурации и версии зависимостей. Образы фиксируем по digest и обеспечиваем доступ к ним независимо от исходного кластера. Секреты восстанавливаем из защищенного хранилища; base64 в YAML не является шифрованием.

Копия etcd сохраняет состояние Kubernetes API, но не содержимое всех Persistent Volume и не внешние S3 или DBaaS. Для stateful-компонентов отдельно резервируем данные. CSI-снимки зависят от поддержки драйвера и доступности хранилища после отказа. Их создание само по себе не задает согласованность нескольких приложений.

В нашем примере Qdrant резервируется штатным механизмом снимков коллекции. Для тестового стенда достаточно одного узла. В распределенной установке нужно учитывать состав шардов и узлов; один локальный снимок нельзя автоматически считать копией всей распределенной коллекции. Возможность восстановления проверяем для конкретной версии и схемы размещения. Файл снимка переносим за пределы исходного узла.

Сохранять каталог работающей БД простым копированием файлов вместо штатного резервирования не будем. При восстановлении после логической ошибки или атаки копия может содержать ту же ошибку: подходящую точку выбирают до повреждения и проверяют в изолированной среде.

Что обсудим в следующей части

Мы разобрали, какие данные и артефакты нужно сохранять для восстановления ИИ-приложения и как организовать резервное копирование в S3, PostgreSQL и Kubernetes. Но наличие копий всех компонентов не гарантирует, что после восстановления они будут соответствовать друг другу. Например, база данных может содержать новую редакцию документа, а поисковый индекс — ссылаться на старую. Или восстановленная копия вернет пользователю доступ к документам, права на которые уже отозваны.

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

Источник: Хабр · статьиПубликуется с разрешения правообладателя, подтверждённого редакцией.Оригинал: Что бэкапить в ИИ-приложении: модель, документы, индексы или историю диалогов? ↗

Есть кому отправить?

Скопируется постоянная ссылка на этот материал.

Комментарии

0

Обсудите материал с другими читателями.

Загружаем комментарии…

Ваш комментарий

Комментарии и оценки — через Яндекс ID