Перенос бакета S3 без остановки Directum RX: зеркалирование, переключение и две ловушки mc mirror
Как перенести документы Directum RX из одного объектного хранилища S3 в другое, не останавливая работу пользователей. Начальная копия, зеркалирование изменений, сверка и переключение, плюс две ловушки mc mirror, из-за которых изменённые документы остаются старыми.
Коротко. Перенос без остановки это начальная копия, догоняющее зеркалирование и переключение. У
mc mirrorбез ключа--overwriteизменённые объекты остаются старыми, аmc diffпри расхождениях возвращает 0. Если сервисы RX ходят в хранилище по имени, которое вы контролируете, переключение обходится без перезапуска.
Хранилище документов на S3 приходится переносить: меняется провайдер, свой MinIO уезжает на новое железо или в другую площадку, кластер пересобирают с другим числом дисков. Документов терабайты, копирование идёт сутками, а остановить систему на сутки никто не даст. Разбираем, как переносить при работающей системе и где при этом тихо теряются изменения. Обе ловушки из статьи мы получили на проверке переноса между двумя MinIO в контейнерах.
Переход с файлового хранилища на объектное это другой сценарий: для него у вендора есть утилита S3Tool, она описана в справке RX. Здесь речь о переносе из одного S3 в другое.
Симптом
Перенос делают «как обычно»: ставят на ночь копирование, утром переключают систему на новое хранилище. Через неделю пользователь открывает документ и видит версию недельной давности или ошибку «файл не найден». Копирование отработало без ошибок, а часть документов, изменённых или созданных во время копирования, в новом хранилище старая или отсутствует.
Почему так
Копирование одним проходом фиксирует состояние на момент, когда каждый объект был прочитан. Всё, что RX записала после этого, в копию не попало. Чем дольше копирование, тем больше таких объектов.
Поэтому перенос без остановки делается в три фазы:
- Начальная копия. Долгая, при работающей системе. Переносит основной объём.
- Догоняющее зеркалирование. Переносит то, что изменилось после начальной копии, и продолжает переносить изменения, пока система работает со старым хранилищем.
- Переключение. Система начинает писать в новое хранилище, зеркалирование доносит последние изменения и останавливается.
Две ловушки mc mirror
mc mirror из клиента MinIO самый частый инструмент для этой работы. У него две особенности, которые
ломают перенос без единого сообщения об ошибке.
Изменённые объекты не обновляются без ключа --overwrite. По умолчанию mc mirror не перезаписывает
объект, который уже есть в целевом бакете. Новые объекты копируются, удалённые с ключом --remove
удаляются, а изменённые остаются в старом виде. На проверке мы перезаписали объект в исходном бакете
при работающем mc mirror --watch: в целевом бакете остался прежний файл размером 110 КБ вместо нового
7,6 КБ. С ключом --overwrite и прошлое расхождение, и новые перезаписи переносятся.
Для RX это важно: содержимое версии документа обычно не перезаписывается, но служебные объекты и повторные
загрузки бывают. Проверять, какие операции у вас реально случаются, дороже, чем всегда ставить --overwrite.
mc diff находит расхождение и завершается с кодом 0. Сверка mc diff печатает строки с отличающимися
объектами, но код возврата у неё нулевой и при найденных расхождениях. Скрипт вида
mc diff ... && echo "всё совпало" скажет, что всё совпало. Проверять нужно, что вывод пустой.
Ещё одно: mc mirror --watch получает изменения через уведомления, которые отдаёт MinIO. Если исходное
хранилище у облачного провайдера, на это рассчитывать нельзя. Там догоняющую фазу делают повторными проходами
без --watch, каждый следующий проход короче предыдущего.
Как переносить
Имена хранилищ в командах: old и new, бакет rx-docs. Адреса и ключи задаются переменными окружения
клиента или командой mc alias set.
Фаза 1. Начальная копия, при работающей системе:
mc mirror --preserve old/rx-docs new/rx-docs
Фаза 2. Догоняющее зеркалирование. Если источник MinIO, запускаем постоянное зеркалирование:
mc mirror --watch --overwrite --remove --preserve old/rx-docs new/rx-docs
Если источник у провайдера, повторяем проходы, пока разница не станет маленькой:
mc mirror --overwrite --remove --preserve old/rx-docs new/rx-docs
Того же можно добиться через rclone: rclone sync old:rx-docs new:rx-docs --checksum. Команда sync
приводит целевой бакет в точное соответствие с исходным, включая удаления.
Сверка перед переключением:
mc diff old/rx-docs new/rx-docs | tee diff.txt
test ! -s diff.txt && echo "расхождений нет"
mc ls --recursive old/rx-docs | wc -l
mc ls --recursive new/rx-docs | wc -l
Пустой вывод diff и одинаковое число объектов. Плюс выборочно открыть несколько документов через систему
после переключения.
Фаза 3. Переключение. Здесь два варианта, и от выбора зависит, будет ли простой вообще.
- Через имя. Если сервис хранилищ RX обращается к S3 по имени, которое вы контролируете (запись DNS или адрес на своём прокси), переключение это смена записи или адреса за прокси. Ключи доступа и имя бакета на новом хранилище должны совпадать со старыми. Сервисы RX не перезапускаются.
- Через настройки RX. Если меняется адрес, ключи или имя бакета, их меняют в параметрах сервиса хранилищ
в
config.ymlи перезапускают сервис. Простой равен времени перезапуска сервиса, минуты, а не сутки.
После переключения зеркалирование оставляют поработать ещё несколько минут: в старое хранилище могли дописаться последние записи, пока сервисы переходили на новое. Затем снова сверка и остановка зеркалирования.
Что ещё проверить
- Версионирование бакета. Если в старом бакете оно включено,
mc mirrorпереносит только текущие версии объектов. Если старые версии нужны, их переносят отдельно или заранее решают, что они не нужны. - Правила жизненного цикла и политики доступа. Они не переносятся вместе с объектами, их настраивают на новом бакете отдельно.
- Место на новом хранилище. С учётом коэффициента избыточности, если это кластер с кодами стирания: полезный объём там меньше суммы дисков.
- Бэкап. Схему бэкапа хранилища перенастраивают на новый бакет в тот же день, а не «потом».
Чего не делать
- Не переключаться после одного прохода копирования. Всё, что изменилось за время копирования, потеряется.
- Не запускать mc mirror без --overwrite. Изменённые объекты останутся старыми.
- Не проверять сверку по коду возврата mc diff. Только по пустому выводу.
- Не удалять старый бакет сразу. Пусть постоит, пока не пройдёт хотя бы один полный цикл бэкапа нового.
Похожая картина у вас?
Разберём ваш контур за 30 минут бесплатного созвона: версия RX, состав сервисов, что болит сильнее всего.
Написать