Максим Иванков рассчитывал тратить на объектное хранилище 25 ₽ в месяц. Через полтора месяца расход приблизился к 10 000 ₽, а темп последних трёх суток давал уже 42 000 ₽ в месяц. Прогноз разошёлся с реальностью в 1680 раз.

В бакете накопилось 291 ГБ данных и 6996 снапшотов. При этом копировать требовалось около 20 ГБ. Иванков описал разбор расходов и конфигурации restic в своей статье на Хабре.

Этот случай полезен тем, кто отправляет копии 1С во внешнее хранилище. Счёт растёт не только из-за объёма базы. На него влияют частота запусков, число запросов, дубли, очистка, класс хранения и восстановление данных.

Цена гигабайта не показывает полный счёт

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

В разборе S3-операций инженер Вячеслав Викулин делит расходы на три части: хранение, запросы к API и исходящий трафик. У некоторых классов добавляется плата за раннее удаление или извлечение.

Статья счётаЧто создаёт расход при бэкапеГде проверить
ХранениеПолные копии, журналы транзакций, старые версии объектов, дубли с других серверовРазмер бакета по префиксам, источникам и классам хранения
PUT, COPY и POSTЗагрузка новых объектов и частей крупных файловДетализация операций у провайдера, журналы доступа
LISTПросмотр содержимого репозитория во время проверки, очистки и поиска данныхЧисло операций по типам, расписание заданий
GETПроверка блоков, чтение метаданных и восстановлениеДетализация запросов, журналы клиента резервного копирования
Исходящий трафикВыгрузка копии на сервер вне облака или в другой регионРаздел трафика в счёте, маршрут восстановления
Раннее удалениеРотация объектов раньше минимального срока холодного классаПолитика хранения, условия выбранного тарифа
Незавершённые загрузкиОставшиеся части multipart-загрузок после сбоевСписок незавершённых загрузок, правила жизненного цикла

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

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

Restic забывал старые копии, но не удалял данные

Restic очищает репозиторий в два этапа. Команда forget исключает старые снапшоты по политике хранения. Команда prune удаляет блоки, которые больше не нужны ни одному оставшемуся снапшоту.

У Иванкова prune не завершался полтора месяца. Шесть виртуальных машин пытались получить эксклюзивную блокировку одного репозитория. В нём также остался лок возрастом 56 часов, а часть пакетов данных пропала.

Политика хранения при такой схеме выглядит рабочей: старые копии исчезают из списка. Объём бакета при этом продолжает расти, потому что forget сам по себе место не освобождает.

Проверять нужно не только код возврата forget. Нужны дата последнего успешного prune, длительность операции и размер репозитория после очистки. Если задание завершилось без ошибки, а объём растёт несколько циклов подряд, ротация не справляется с потоком новых данных.

Запускать независимый prune с каждой машины тоже не следует. Одному репозиторию нужен один процесс очистки по общему расписанию. Иначе задания спорят за блокировку, а оператор видит череду ошибок вместо предсказуемой ротации.

Дубль занял две трети репозитория

Сбой очистки объяснял часть роста, но не все 291 ГБ. Разбор содержимого показал ещё два источника расходов:

Репозиторий вырос до 291 / 20 = 14,55 объёма целевых данных. Один дубль занял 190 / 291 × 100 = 65,3% всего бакета.

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

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

Запуск каждые две минуты умножил число обращений

Журналы двух баз отправлялись в облако каждые две минуты. Для одной базы это 24 × 60 / 2 = 720 запусков в сутки. Для двух баз — 1440 запусков, а за условный месяц из 30 дней — 43 200.

Каждый запуск restic создавал десятки или сотни обращений к объектному хранилищу. Умножать 43 200 запусков на произвольное число запросов нельзя: в опубликованном разборе нет полного журнала операций. Там же нет тарифа Яндекса для каждой операции в этом случае.

Но порядок проверки уже понятен. Если размер данных выглядит разумно, а счёт продолжает расти, сопоставьте число запусков с количеством PUT, LIST, GET и других операций. Интервал задания — такая же часть бюджета, как глубина хранения.

Частота должна следовать из допустимой потери данных. Если компании нужен журнал каждые две минуты, расходы на такой режим нужно принять и заранее посчитать по фактическим операциям. Если допустима потеря часа, десятки тысяч запусков в месяц не дают дополнительной пользы.

Не меняйте интервал одного задания, не проверив соседние. У Иванкова работали два таймера отправки, но до 30 минут замедлили только один. Второй продолжал создавать прежний поток.

Один процесс очистки остановил рост

Иванков оставил один ежедневный prune в 03:30. Срок хранения журналов обеих баз сократил до трёх дней, убрал дубль и лишние данные.

БылоЧто изменилиСтало
291 ГБ в репозиторииУдалили дубли и выполнили физическую очистку54,7 ГБ после очистки
6996 снапшотовСократили ротацию журналов1282 снапшота
Шесть конкурирующих заданий pruneОставили один скрипт по расписаниюОдин запуск ежедневно в 03:30
Хранение журналов 14 и 7 днейДля обеих баз поставили срок три дняОдна понятная политика
Рост без контрольной точкиНаблюдали репозиторий ещё полтора месяца57,6 ГБ и 848 снапшотов

Объём сократился на (291 − 54,7) / 291 × 100 = 81,2%. Число снапшотов уменьшилось примерно на 81%. Совпадение долей само по себе ничего не доказывает, но показывает масштаб лишнего потока.

Через полтора месяца объём держался около 57,6 ГБ. Это важнее разового падения после prune: очистка работает, когда репозиторий стабилизируется после нескольких циклов ротации.

Для 20 ГБ целевых данных коэффициент установился на уровне 57,6 / 20 = 2,88. Это результат одного случая, а не норма для restic или 1С. В другом репозитории коэффициент изменят срок хранения, доля изменений, число баз и устройство копий.

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

Как связать объектное хранилище с бэкапом 1С

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

Для SQL Server порядок настройки и ротации описан в инструкции по бэкапу 1С средствами SQL Server. Общую схему с локальной и внешней копией можно сверить с руководством по резервному копированию 1С.

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

Разведите задания по ролям:

ЗаданиеЧто передаётКак контролировать
Полный бэкап СУБДФайл полной копии базыВремя создания, размер, результат проверки
Журнал транзакцийИзменения между полными копиямиИнтервал, число файлов, срок хранения
Отправка во внешний бакетУже созданные файлы копийЧисло загруженных объектов и операций
РотацияУдаление копий старше принятого срокаСписок оставшихся точек восстановления
pruneФизическое освобождение местаДата успеха и объём после завершения
Тестовое восстановлениеПроверка пригодности копииОтдельная база, время и результат запуска

Эта схема отделяет создание копии от её доставки и очистки. Если счёт вырос, вы увидите конкретный этап, а не одно общее задание «бэкап прошёл».

Как оценить следующий счёт

Не переносите тариф AWS, Backblaze или другого сервиса на Яндекс Облако. Даже при совместимом S3 API провайдеры по-разному считают запросы, трафик, холодное хранение и раннее удаление.

Возьмите детализацию своего счёта за день и сопоставьте её с расписанием. Например, 1440 запусков за сутки — расчёт из двух баз и двухминутного интервала. Число операций берите из отчёта провайдера, а не из средней оценки для restic.

После этого соберите месячный прогноз по четырём строкам:

хранение + запросы + исходящий трафик + дополнительные условия класса.

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

Проверка бакета перед следующим расчётным периодом

Пройдите этот список по действующему репозиторию:

  1. Сравните объём исходных данных с размером бакета.
  2. Разделите содержимое по серверам, базам и типам копий.
  3. Найдите дубли основного и резервного узлов.
  4. Проверьте дату последнего успешного prune.
  5. Посчитайте запуски каждого задания за сутки.
  6. Разделите счёт на хранение, запросы, трафик и раннее удаление.
  7. Поставьте уведомления на рост объёма и числа объектов.

В случае Иванкова 20 ГБ целевых данных превратились в 291 ГБ репозитория. После исправлений объём установился около 57,6 ГБ. Для своей системы рассчитайте тот же коэффициент и подпишите, какую часть создают полные копии, журналы и срок хранения. Остаток без объяснения — повод открыть детализацию до следующего счёта.

restic бэкап 1с облачные расходы объектное хранилище резервное копирование