- PVSM.RU - https://www.pvsm.ru -

Представим типичную инфраструктурную задачу. В компании для хранения артефактов сборки, бэкапов сервисов или пользовательских файлов применяется S3‑хранилище. Развернуто оно в основном контуре — например, в продакшен-кластере.
Но что, если этот кластер выйдет из строя по причине, скажем, сетевого сбоя или человеческого фактора? Весь проект может остаться без критически важных данных. Решение очевидно: данные должны периодически копироваться во второй контур — резервный дата-центр, отдельную катастрофоустойчивую инфраструктуру, возможно даже в другом регионе.
Привет! На связи Сергей, проектировщик интерфейсов в Selectel [1]. В этой статье разберем, как настроить клиентскую синхронизацию между двумя хранилищами с помощью MinIO Client. Рассмотрим все шаги для подготовки окружения, установки клиента и настройки автоматического запуска, — чтобы объекты регулярно копировались из одного бакета в другой.
Пригодится всем, кто работает с инфраструктурой, распределенной по нескольким дата-центрам, тестовыми и рабочими окружениями, а также при проектировании катастрофоустойчивых сценариев.
Содержание
→ Основные понятия [2]
→ Клиентская синхронизация vs серверная репликация [3]
→ Типы синхронизации в MinIO [4]
→ Требования к окружению [5]
→ Выполняем синхронизацию [6]
→ Ограничения и риски при репликации через mc mirror [7]
→ Особенности mc mirror и альтернативы [8]
Итак, допустим, основное S3‑хранилище находится в Санкт-Петербурге — именно туда сервисы загружают объекты. Чтобы при сбое на первой площадке компания не потеряла доступ к данным, разворачивается резервный кластер в Москве. Именно эту задачу и решает синхронизация бакетов.
Суть синхронизации сводится к копированию объектов из исходного бакета в целевой. Реализовать этот процесс можно по‑разному: от встроенной серверной репликации до самописных скриптов. Очень удобной оказывается утилита MinIO Client (mc) — универсальный инструмент, который работает с любым S3‑совместимым API и избавляет от необходимости писать собственный код для проверки состояния файлов.
За перенос данных в клиенте отвечает команда mc mirror, которая:
сравнивает содержимое исходного и целевого бакетов;
копирует новые и измененные объекты;
опционально удаляет из целевого хранилища те объекты, которых уже нет в источнике.
Важно учитывать, что mc mirror не выполняет непрерывную репликацию в реальном времени. Утилита работает исключительно по запросу, и каждый ее запуск инициирует полное сканирование обоих бакетов. Чтобы постоянно поддерживать актуальность данных в резервном хранилище, этот процесс необходимо автоматизировать самостоятельно с помощью внешних инструментов — например, планировщика cron, настройку которого разберем далее.
Если в целевом бакете включено версионирование [9], любое обновление объекта приведет к созданию его новой версии. В таком случае может произойти неконтролируемый рост занимаемого хранилищем, дискового пространства. Для базовых задач синхронизации включать эту опцию не обязательно.
Организовать обмен данными между независимыми площадками можно по‑разному. Один способ — задействовать встроенные механизмы самих S3‑кластеров. Другой — управлять процессом извне с помощью отдельных утилит.
mc replicate — встроенный механизм MinIO, работающий на стороне самого хранилища. В отличие от клиентской синхронизации, репликация реагирует на события создания и изменения объектов в реальном времени и автоматически отправляет новые данные на резервную площадку.
Особенности:
автономность — процесс протекает в фоновом режиме, не требует запуска вручную или настройки внешних планировщиков;
точность — фиксируются любые операции с объектами: от создания и модификации до полного удаления, что обеспечивает строгую консистентность бакетов;
ограниченная совместимость — инструмент работает исключительно с хранилищами MinIO, применить его для других S3-совместимых решений не получится.
Серверная репликация идеально подходит для задач, требующих работы с данными в реальном времени и работает только внутри экосистемы одного вендора.
Именно этот способ мы разберем в статье. Команда mc mirror запускается вручную или по расписанию, просматривает содержимое исходного и целевого бакетов, сравнивает их, а затем копирует недостающие или измененные объекты на резервную площадку.
Особенности:
простота — синхронизация выполняется только при вызове команды, поэтому для непрерывности процесса требуется внешний планировщик;
дискретность — в отличие от репликации, клиент не отслеживает операции в реальном времени;
универсальность — инструмент не привязан к конкретному вендору и может работать с разными S3-совместимыми хранилищами.
Пример:
mc mirror source/bucket target/bucket
Клиентская синхронизация незаменима при миграции между разными S3-провайдерами или для периодического резервного копирования. Именно поэтому в статье мы рассматриваем mc mirror — инструмент максимально универсальный, независимый от архитектуры хранилища, и, при этом, чрезвычайно простой в использовании.

Бесплатный курс «Системный администратор Linux с нуля»
Освойте администрирование Linux на SelectOS и станьте востребованным специалистом.
Зарегистрироваться → [10]
В распределенных архитектурах новые объекты часто создаются одновременно на двух независимых площадках. Например, если часть сервисов работает в Москве, другая — в Санкт-Петербурге, то оба кластера параллельно принимают трафик на запись. В подобных сценариях требуется двунаправленная синхронизация, чтобы любые изменения в одном бакете встречно транслировались и в другой.
Cluster 1 (СПб) ◄────► Cluster 2 (Москва)
Для такого режима в mc mirror есть флаг --active-active. Он активирует двустороннюю синхронизацию. Важно: команду нужно выполнить на каждой из площадок. При конфликте, — когда один и тот же объект изменился в обоих местах, — побеждает более свежая по времени изменения версия.
# Запускается на каждой площадке!
mc mirror --active-active s3-ru7/backups s3-ru3/backups-replica
Особенности:
параллельная запись — все кластеры остаются полностью доступны для добавления и модификации файлов;
встречный обмен — изменения распространяются в оба направления при каждом запуске синхронизации;
требуется осторожность и четкое понимание логики приложения — например, без флага --remove риск случайной потери данных меньше, но удаленные на одной площадке файлы могут восстанавливаться с соседнего кластера при следующем цикле синхронизации.
Если нужно поддерживать актуальные копии данных сразу на нескольких площадках достаточно выполнить команду mc mirror соответствующее количество раз — по одному на каждый целевой бакет.
Primary (ru-3) ─────► Replica 1 (ru-7)
Primary (ru-3) ─────► Replica 2 (ru-9)
Важно понимать: mc mirror всегда работает с парой «один источник — один целевой бакет». Схема с тремя и более равнозначными кластерами, синхронизирующими друг друга в произвольном порядке, mc mirror не поддерживается. Для полноценной веерной синхронизации между MinIO-кластерами потребуется серверная репликация с помощью mc admin replicate.
Особенности:
индивидуальный запуск — каждый целевой бакет требует отдельного выполнения команды;
оптимально для георезервирования — подходит для простых сценариев резервирования в несколько регионов.
Прежде чем переходить к настройке, давайте подготовим инфраструктуру. В соответствии с выбранным сценарием, развернуты два кластера: основной кластер в Санкт-Петербурге и резервный в Москве. Для работы синхронизации потребуется несколько компонентов.
Нам понадобится два бакета — по одному в каждой локации. У бакетов должен быть доступный S3 API-эндпоинт. В качестве примера рассмотрим следующие адреса::
s3.ru-3.storage.selcloud.ru — Санкт-Петербург (исходный бакет),
s3.ru-7.storage.selcloud.ru — Москва (целевой бакет).
Для авторизации утилиты потребуется выделить отдельного пользователя или создать сервисный аккаунт, обладающий доступом к обоим хранилищам.
Базовый набор IAM-политик должен разрешать чтение данных из источника и их запись на резервную площадку. Если же планируется строгая синхронизация с очисткой неактуальных файлов (при использовании флага --remove), учетной записи дополнительно потребуются привилегии на удаление объектов в целевом бакете.
И последний инфраструктурный компонент — mc, утилита командной строки MinIO Client, которая дает возможность управлять хранилищем. С ее помощью можно:
подключаться к кластерам MinIO,
создавать бакеты,
включать версионирование,
настраивать правила репликации,
проверять статус синхронизации данных.
Именно через mc мы будем выполнять все дальнейшие настройки.
Теперь можно переходить к практической части. Алгоритм будет следующий.
Установим MinIO Client (mc) — подготовим инструмент для взаимодействия с инфраструктурой.
Создадим бакеты — развернем их на исходной и целевой площадках, между которыми будет происходить перенос данных.
Подключим оба бакета через alias — добавим исходный и целевой S3 в конфигурацию mc, чтобы работать с ними в рамках одной команды.
Запустим синхронизацию вручную — проверим, что все работает, прежде чем автоматизировать.
Проверяем, что синхронизация выполнена — получим подтверждение, что первые действия вручную успешно отработали.
Автоматизируем запуск — настроим планировщик cron, чтобы синхронизация запускалась по расписанию.
Проверим результат — загрузим файл и убедимся, что он появился во втором хранилище.
Начнем с установки MinIO Client на сервер или локальную машину, на которой будет запускаться синхронизация.
Для установки утилиты потребуется загрузить бинарный файл, сделать его исполняемым и добавить директорию с ним в системную переменную PATH:
curl https://dl.min.io/client/mc/release/linux-amd64/mc
--create-dirs
-o $HOME/minio-binaries/mc
chmod +x $HOME/minio-binaries/mc
export PATH=$PATH:$HOME/minio-binaries/
На macOS проще всего установить MinIO Client с помощью менеджера пакетов Homebrew:
brew install minio/stable/mc
В этом случае придется немного попотеть.
Скачиваем MinIO Client с официального сайта [11] и кладем бинарник в удобную директорию — например, C:toolsmc.
Чтобы вызывать клиент из любой папки, путь к нему нужно прописать в системе. Для этого через поиск Windows найдем раздел «Изменение системных переменных среды», откроем меню «Переменные среды», выберем переменную Path и нажав кнопку «Изменить» добавим директорию с mc.
Чтобы новые значения переменных окружения вступили в силу, бывает нужно перезапустить терминал (в некоторых случаях — саму операционную систему).
Проверим корректность установки с помощью простой команды в PowerShell:
mc --version
Успешный вывод версии говорит о готовности к работе. Можно двигаться дальше.
Если при подключении возникает ошибка верификации, потребуется единоразово добавить сертификат хранилища вручную.
Откроем в браузере адрес S3-эндпоинта — например, https://s3.ru-7.storage.selcloud.ru.
Нажмем на значок сертификата (иконка закрытого замка) в адресной строке и скачиваем сертификат
Откроем скачанный файл, перейдем на вкладку Состав и выберем опцию Копировать в файл.
Сохраняем в формате Base-64 encoded X.509 (.cer).
После этого можно корректно работать с эндпоинтом S3 без ошибок TLS.
Теперь, когда MinIO Client установлен и готов к работе, можно подключить наши бакеты в ru-3 (Санкт-Петербург) и ru-7 (Москва). Потребуется несколько шагов.
В нашей онлайн-документации есть инструкция по подключению MinIOс Client к S3 Selectel [12].
Бакетов понадобится два, в разных регионах. Однако поскольку создание одного из них ничем не отличается от другого, рассмотрим весь процесс на единственном примере.
В панели управления [13] в верхнем меню откроем Продукты и перейдем в S3 и далее в раздел Бакеты. Нажмем Создать бакет.
Придумаем имя для бакета. Здесь есть пара ограничений, которые диктуют совместимость с S3 API. Во‑первых, имя должно быть уникальным среди всех пользователей в том же пуле [14]. Во‑вторых, допустимы только некоторые символы: цифры, латинские буквы, точка и дефис. Полные правила — в документации Amazon: Bucket naming rules [15].
Выберим регион и пул [16]. В нашем примере первый бакет расположен в санкт‑петербургской локации ru-3, второй — в московской ru‑7.
В блоке Конфигурация зададим параметры хранилища.
Тип доступа выберем Приватный — наши бакеты для резервного копирования, публичный доступ им ни к чему.
Класс для бэкапов подойдет Холодное хранение — обращение к данным происходит нечасто. Важно: класс нельзя изменить после создания бакета.
Тип адресации: возьмем vHosted — это рекомендуемый вариант для работы с S3 API.
Версионирование для базовой синхронизации включать не обязательно. Если требуется хранить историю изменений объектов — нужно отметить чекбокс Версионирование в блоке Защита данных, но надо иметь в виду, что это существенно увеличит объем хранилища.
Нажмем Создать бакет.
Шаги выше повторим для другого региона.
Для взаимодействия с обоими хранилищами утилите mc mirror потребуются ключи доступа.
Согласно лучшим практикам безопасности, вместо использования реквизитов владельца аккаунта следует завести отдельного сервисного пользователя — специальную учетную запись. У него не будет права входить в панель управления, но он сможет иметь доступ к ресурсам: скриптам, автоматизированным задачам и утилитам.
Процесс создания учетной записи состоит из нескольких простых шагов.
В верхнем меню панели управления нажмем IAM и перейдем в раздел Сервисные пользователи.
Нажмем Добавить сервисного пользователя и придумаем ему имя — например, s3-mirror-bot.
В блоке Настройки доступа добавим разрешение. Область доступа — Аккаунт или Проекты При выборе второго варианта укажем проект, в котором находятся бакеты. Роль — s3.admin, что достаточно для чтения и записи объектов через S3 API.
Нажмем Добавить пользователя.
Сервисный пользователь не может сгенерировать ключи самостоятельно. Эту операцию выполняет владелец инфраструктуры или администратор с ролью iam.admin. Последовательность действий следующая.
Откроем страницу только что созданного пользователя и перейдем на вкладку Доступ.
В блоке S3-ключи нажмем Добавить ключ и введем произвольное имя — например, mirror-ru3, после чего выберем проект с первым бакетом в ru-3.
Нажмем Сгенерировать.
Скопируем и сохраним оба значения: Access key и Secret key. После закрытия окна Secret key нигде больше не отобразится. Если он потерян, придется генерировать ключ заново.
Повторим все шаги и для второго проекта в ru-7, назвав ключ, например, mirror-ru7.
Теперь у нас два набора ключей — по одному на каждый регион. Именно их мы будем использовать при настройке алиасов в mc.
Каждый регион Selectel — это отдельный S3-эндпоинт. В mc мы создаем для них «псевдонимы» (alias), чтобы легко работать — не набирать каждый раз длинные строки, рискуя опечаться:
mc alias set s3-ru3 https://s3.ru-3.storage.selcloud.ru <AccessKey> <SecretKey>
mc alias set s3-ru7 https://s3.ru-7.storage.selcloud.ru <AccessKey> <SecretKey>
Псевдонимы в примере выше:
s3-ru3 — основной бакет ru-3 в Санкт-Петербурге,
s3-ru7 — резервный бакет ru-7 в Москве.
<AccessKey> <SecretKey> — значения соответствующих полей из S3-ключей [17].
Теперь mc знает, где искать каждый бакет.
Чтобы убедиться, что все работает и mc видит бакеты, выполним:
mc ls s3-ru3
mc ls s3-ru7
Должен появиться список бакетов в каждом регионе. Если ошибки нет — подключение успешно.
Отлично, у нас есть два подключенных бакета. Теперь — главное: настроим автоматическое копирование данных из Санкт-Петербурга в Москву.
Для начала запустим синхронизацию вручную, чтобы убедиться, что все работает:
mc mirror --overwrite --remove s3-ru3/backups s3-ru7/backups-replica
Разберем, что делает эта команда:
берет все объекты из источника в ru-3,
копирует их в резервное хранилище ru-7,
принудительно обновляет измененные файлы за счет флага --overwrite,
благодаря действию флага --remove удаляет из целевой площадки лишние объекты, которых больше нет в бакете-источнике.
Если в исходном хранилище уже есть данные, копироваться они начинают незамедлительно.
Проверим на простом примере. Загрузим файл в основной бакет:
mc cp test.txt s3-ru3/backups/
Снова запустим синхронизацию:
mc mirror --overwrite --remove s3-ru3/backups s3-ru7/backups-replica
Убедимся, что объекты появились во втором регионе:
mc ls s3-ru7/backups-replica
Если все подключено и настроено правильно, вывод команды mc ls покажет файл test.txt.
На предыдущем шаге мы запускали синхронизацию вручную. Но в реальной жизни нужен автоматический механизм. В Linux для этого используется cron — системный планировщик задач.
Следующая команда открывает на редактирование нужный конфигурационный файл:
crontab -e
Добавляем строку, которая будет запускать синхронизацию каждую минуту. Важное уточнение: отрезок времени приведен для примера. На практике использовать столь короткие промежутки — не самая хорошая идея, так как возникает неоправданная нагрузка и риск конфликтов между не завершившимся задачами.
* * * * * mc mirror --overwrite --remove s3-ru3/backups s3-ru7/backups-replica
Разберем эту строку:
* * * * *
│ │ │ │ └── день недели (0-7, 0 и 7 = воскресенье)
│ │ │ └──── месяц (1-12)
│ │ └────── день месяца (1-31)
│ └──────── час (0-23)
└────────── минута (0-59)
Пять звездочек (* * * * *) = выполнять каждую минуту
После сохранения конфигурации схема будет работать по следующему алгоритму.
Сторонний сервис загружает файл в исходный бакет в ru-3.
В течение заданного промежутка времени (в примере минуты) срабатывает cron.
Утилита mc mirror сканирует хранилище, обнаруживает изменения и переносит данные на резервную площадку ru-7.
Никакого ручного вмешательства больше не требуется. Главное — иметь постоянно работающий сервер [18], который позволит раз в заданное время применять данную команду.
До этого момента мы рассматривали базовый сценарий, при котором содержимое исходного бакета переносится целиком. На практике так бывает не всегда.
В одном бакете могут одновременно находиться рабочие файлы, резервные копии, временные выгрузки, логи и прочее. Далеко не всегда все это нужно отправлять во второй регион. Во многих случаях задача звучит иначе — синхронизировать только полезные данные, а все лишнее — исключить.
Именно для таких случаев в mc mirror предусмотрены фильтры. Самый частый сценарий — исключить из репликации временные или ненужные данные. Для этого можно воспользоваться параметром --exclude. Например, чтобы проигнорировать файлы с расширением .tmp:
mc mirror --exclude "*.tmp" s3-ru3/backups s3-ru7/backups-replica
Все объекты, не попавшие под это правило синхронизируются как обычно.
Иногда наоборот требуется переносить не все, а только конкретный тип данных. Выручит параметр с противоположным действием — --include. Например, дублироваться на резервном хранилище должны только файлы .jpg:
mc mirror --include "*.jpg" s3-ru3/backups s3-ru7/backups-replica
Во второй регион попадут только файлы с указанным расширением.
В рамках одного запроса фильтры можно объединять, если требуется более точная логика:
mc mirror
--include "*.jpg"
--exclude "archive/*"
s3-ru3/backups s3-ru7/backups-replica
В примере выше изображения будут синхронизироваться, но только не те, что расположены в архивном каталоге.
Зачастую эффективнее отбирать объекты не по расширению, а отталкиваясь от готовой структуры каталогов. Если целевые файлы уже сгруппированы в отдельной папке, достаточно указать соответствующий префикс прямо в путях источника и назначения:
mc mirror s3-ru3/backups/db s3-ru7/backups-replica/db
Несмотря на всю простоту данной схемы репликации, отрабатывает она не идеально.
Важно понимать базовую вещь: mc mirror не отслеживает изменения в реальном времени. Каждый запуск работает по одному принципу:
получает список объектов в исходном бакете,
получает список объектов в бакете целевом,
вычисляет различия,
выполняет копирование.
То есть это полный сравнительный проход, а не обработка событий. Такой способ может привести сразу к нескольким проблемам.
В первую очередь, накладные расходы на LIST-операции линейно растут вместе с количеством объектов. Соответственно при «тяжелых» бакетах синхронизация становится заметно медленнее, а частые запуски выдают «diff overhead».
При росте количества объектов синхронизация даже самых маленьких изменений может обойтись в серьезные суммы — ведь каждый раз запрашивается полный список объектов и сравнивается каждый из них.
При использовании --remove целевой бакет становится точной копией исходного. Это означает, что mc не только добавляет новые объекты и обновляет измененные файлы, но и удаляет все, чего нет в источнике. Возникает опасность деструктивной очистки, ведь «нет в source-бакете» не всегда означает «не нужен».
Например, если upstream-система на какое‑то время перестала писать данные, очистила временные файлы, пересоздала структуру бакета, то с флагом --remove ситуация в точности воспроизведется и в downstream‑хранилище. Целевой бакет будет просто «зеркалить» проблему. Для защиты критически важных данных на резервной площадке, можно воспользоваться механизмом S3 Object Lock [19], заблокировав возможность удаления определенных объектов.
mc mirror — это все-таки инструмент синхронизации состояния, а не полноценная система доставки или репликации данных.
Если от системы ожидается появление файла во втором регионе «почти сразу после загрузки» — mc mirror здесь не поможет. Он не реагирует на событие создания объекта, а периодически сравнивает два состояния. Время доставки зависит от частоты запуска — и ее невозможно гарантировать.
Особенно плохо mc mirror чувствует себя в системах, где много мелких файлов, происходят постоянные изменения, а жизненный цикл объектов очень короткий. В таком случае один и тот же набор объектов постоянно пересчитывается, из-за чего создается избыточная нагрузка на S3 LIST и фактическая синхронизация начинает занимать заметное время даже без изменений.
Лучшее решение — сочетание двух подходов. Событийная (event-driven) модель берет на себя оперативную доставку: вместо сравнения состояний система реагирует на сами события изменения объектов, поэтому постоянные LIST-запросы не нужны. А периодический mc mirror подключается отдельно — не для основной доставки данных, а для сверки состояний и устранения возможных расхождений.
mc mirror — это удобный инструмент синхронизации S3-хранилищ, но важно правильно понимать его роль. Такой способ репликации хорошо подходит там, где допустима задержка, а простота важнее, чем строгая событийность — например, для простого переноса данных. А вот в случаях, где важна минимальная задержка, критична строгая консистентность и контроль операций, mc mirror уже не так эффективен.
Автор: Tsuoko
Источник [20]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/selectel/454708
Ссылки в тексте:
[1] в Selectel: https://selectel.ru/services/cloud/storage/?utm_source=habr.com&utm_medium=referral&utm_campaign=cloud_article_minio_070726_content
[2] Основные понятия: #basic
[3] Клиентская синхронизация vs серверная репликация: #ways
[4] Типы синхронизации в MinIO: #types
[5] Требования к окружению: #requirements
[6] Выполняем синхронизацию: #perform
[7] Ограничения и риски при репликации через mc mirror: #restrictions
[8] Особенности mc mirror и альтернативы: #alternatives
[9] версионирование: https://habr.com/ru/companies/selectel/articles/906898/
[10] Зарегистрироваться →: https://study.selectel.ru/admincourse/?utm_source=habr.com&utm_medium=referral&utm_campaign=courselinux_article_minio_070726_banner_ord
[11] с официального сайта: https://dl.min.io/client/mc/release/windows-amd64/mc.exe
[12] инструкция по подключению MinIOс Client к S3 Selectel: https://docs.selectel.ru/s3/tools/minio-client/?utm_source=habr.com&utm_medium=referral&utm_campaign=docs_article_minio_070726_content
[13] В панели управления: https://my.selectel.ru/storage/?utm_source=habr.com&utm_medium=referral&utm_campaign=myselectel_article_minio_070726_content
[14] пуле: https://docs.selectel.ru/infrastructure/locations/#pool?utm_source=habr.com&utm_medium=referral&utm_campaign=docs_article_minio_070726_content
[15] Bucket naming rules: https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
[16] регион и пул: https://docs.selectel.ru/infrastructure/locations/?utm_source=habr.com&utm_medium=referral&utm_campaign=docs_article_minio_070726_content
[17] S3-ключей: https://docs.selectel.ru/s3/tools/minio-client/?install-client=macos#configure-access&utm_source=habr.com&utm_medium=referral&utm_campaign=docs_article_minio_070726_content
[18] постоянно работающий сервер: https://selectel.ru/services/cloud/servers/?utm_source=habr.com&utm_medium=referral&utm_campaign=cloud_article_minio_070726_content
[19] S3 Object Lock: https://habr.com/ru/companies/selectel/articles/1007034/
[20] Источник: https://habr.com/ru/companies/selectel/articles/1056218/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1056218
Нажмите здесь для печати.