MAATRIX / Блог / Миграция файлового хранилища на терабайты: как не ждать неделю

Миграция файлового хранилища на терабайты: как не ждать неделю

MAATRIX

Вы запускаете rsync -avz /data/ user@newserver:/data/ на 20 терабайтах фото и видео, смотрите на счётчик прогресса — и понимаете, что перенос закончится где-то через неделю. К этому моменту уже назначена дата отключения старого сервера, а половина данных ещё лежит на нём. Дальше — практическая раскладка, как сократить это время до разумного: где параллелить, где сжатие только мешает, как честно посчитать срок и когда сеть вообще не лучший вариант. Если заодно подбираете конфигурацию под новое хранилище — отдельно про диски и сеть под такой объём есть в статье про выделенный сервер для файлового хранилища на терабайты.

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

Наивный запуск rsync — это один процесс, который читает файлы по очереди, для каждого делает stat, решает, нужно ли его копировать, и передаёт по одному TCP-соединению. Узкое место здесь не диск и не сеть сама по себе, а то, что один поток редко успевает загрузить канал целиком:

  • Одно TCP-соединение упирается в произведение задержки и окна — на маршруте с приличным RTT (типично между дата-центрами в разных странах, например RU–UK) одна сессия может не выбирать всю заявленную полосу, даже если канал 1 Гбит/с или больше.
  • Много мелких файлов — это много накладных расходов на файл, а не на байт. Миллион мелких превьюшек и мелких документов передаются кратно дольше, чем тот же объём в виде десятка больших архивов, потому что на каждый файл уходит время на stat, открытие, закрытие соединения на уровне протокола rsync.
  • CPU для чтения/сравнения контрольных сумм тоже упирается в один поток — ядро на источнике простаивает, пока используется только одно.

Итог: если у вас 20 ТБ фото, видео и архивов и один процесс rsync тянет, скажем, в разы меньше от паспортной скорости канала — это не значит, что сеть плохая, это значит, что вы не используете её резерв.

Параллелизация: несколько rsync вместо одного

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

Вариант 1 — вручную по подкаталогам верхнего уровня. Если у вас /data/photos, /data/video, /data/archive и так далее — запускайте по процессу на каждый:

rsync -avh --stats /data/photos/  user@newserver:/data/photos/  &
rsync -avh --stats /data/video/   user@newserver:/data/video/   &
rsync -avh --stats /data/archive/ user@newserver:/data/archive/ &
wait

Вариант 2 — через xargs, если подкаталогов много и они примерно одного размера:

ls -1 /data/source | xargs -n1 -P8 -I{} \
  rsync -avh --stats /data/source/{} user@newserver:/data/target/{}

Флаг -P8 здесь — восемь параллельных процессов; это отправная точка для эксперимента, не догма. Если каталоги сильно различаются по размеру, лучше сначала посчитать объём каждого (du -sh /data/source/*/) и распределить их по потокам вручную, чтобы не получилось так, что семь потоков уже закончили, а восьмой тащит основной объём в одиночку.

Вариант 3 — GNU parallel, если он уже стоит на сервере:

find /data/source -maxdepth 1 -mindepth 1 -type d | \
  parallel -j 8 rsync -avh {} user@newserver:/data/target/

Для действительно больших деревьев с миллионами мелких файлов существуют специализированные обёртки над rsync (например parsyncfp или msrsync), которые сами разбивают файловое дерево на пакеты и распараллеливают — их стоит поставить отдельно и почитать документацию, если ручное разбиение по каталогам оказывается неудобным из-за неравномерной структуры данных.

Важная оговорка: параллелизация даёт прирост, только если у канала и у дисков есть свободный резерв. Если источник — это одиночный жёсткий диск с медленным случайным чтением мелких файлов, восемь параллельных rsync будут драться за головку диска и почти не ускорят дело, а то и замедлят его дополнительной конкуренцией за I/O. Проверяйте загрузку диска (iostat -x 1) и сети (iftop или nload) во время теста — если диск уже под 100% при одном потоке, добавление потоков не поможет.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Сжатие на лету: `-z` помогает не всегда

Флаг -z в rsync включает сжатие данных перед передачей и распаковку на другом конце — это может ощутимо сократить объём передаваемых байт, но только для сжимаемых данных:

Тип данныхСтоит ли -zПочему
Текстовые файлы, логи, CSV/JSON, дампы БД в текстовом видеДаХорошо сжимаются, экономия трафика заметна
Исходный код, конфигиДаТо же самое, плюс объём обычно небольшой
JPEG, PNG (уже сжатые форматы)НетУже сжаты алгоритмом формата, повторное сжатие почти не уменьшает размер
Видео (H.264/H.265/большинство современных кодеков)НетАналогично — сжатие бессмысленно, только грузит CPU
Уже упакованные архивы (zip, 7z, tar.gz)НетВнутри уже плотное сжатие, вторая попытка ничего не даёт

Для фото- и видеоархивов — а именно они чаще всего составляют основной объём при миграции файлового хранилища на терабайты — -z почти всегда не нужен: вы тратите циклы CPU на попытку сжать то, что и так плотно упаковано, а выигрыша в объёме передачи почти нет. Хуже того, на быстром канале именно CPU-сжатие может стать новым узким местом: канал ждёт, пока процессор досожмёт очередной блок.

Если у вас смешанный набор — часть текстовая, часть уже сжатая, — можно не выключать -z целиком, а исключить конкретные расширения из сжатия через --skip-compress:

rsync -az --skip-compress=jpg/jpeg/png/mp4/mkv/mov/webp/zip/gz/7z/rar \
  -avh --stats /data/source/ user@newserver:/data/target/

Практическое правило: если по объёму у вас преобладают фото/видео/архивы — просто уберите -z из команды целиком и не тратьте на него внимание. Если преобладает текстовая нагрузка — включайте.

Как реально посчитать время переноса, а не гадать по паспортной скорости

Самая частая ошибка в планировании — делить объём данных на скорость канала, указанную в договоре с провайдером («у нас 1 Гбит/с»), и получать красивую, но нереалистичную цифру.

Наивный расчёт: 20 ТБ / 1 Гбит/с (≈125 МБ/с теоретически) ≈ 44 часа. На практике редко получается так гладко — реальная скорость почти всегда заметно ниже паспортной из-за накладных расходов протокола TCP, задержки маршрута, конкуренции с другим трафиком на канале, ограничений дисковой подсистемы на чтение/запись мелких файлов и того, что канал часто разделяется с другими сервисами дата-центра.

Правильная методика:

  1. Возьмите репрезентативную выборку — 50–100 ГБ, но обязательно с тем же составом файлов, что и весь массив (не только крупные видео, но и характерную долю мелких файлов, если она есть в реальных данных).
  2. Прогоните перенос той же командой и с теми же флагами, что планируете использовать для полного переноса (в том числе с той же параллелизацией).
  3. Замерьте фактическую скорость. У rsync в конце вывода с --stats или -v есть строка вида sent X bytes ... Y bytes/sec — это и есть измеренная скорость на вашем реальном канале и с вашим реальным набором файлов, а не паспортная цифра провайдера.
  4. Посчитайте оценку времени по формуле: полный объём данных / измеренная скорость = ориентировочное время. Это именно ориентир, а не гарантия — на длинном переносе за много часов вмешаются суточные колебания загрузки канала, фоновые задачи на серверах и другие факторы.
  5. Добавьте запас — на практике имеет смысл закладывать дополнительные 30–50% сверх расчётного времени на непредвиденные паузы, обрывы соединения и повторные попытки для файлов, которые не докопировались с первого раза.

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

Когда физическая перевозка диска быстрее сети

Для действительно больших объёмов — десятки терабайт и больше — есть вариант, который звучит старомодно, но остаётся рабочим: скопировать данные на внешний накопитель локально (без сети вообще) и физически перенести этот накопитель на новый сервер, если оба физически доступны в одном дата-центре или могут быть доставлены через remote-hands.

Логика простая: локальное копирование по SATA/USB3/NVMe почти всегда быстрее сетевой передачи через интернет-канал между дата-центрами, особенно если сеть ограничена задержкой маршрута или делится с другим трафиком. При объёме в 30–50+ ТБ разница может составлять не часы, а дни.

Практическая последовательность:

  1. Подключите к серверу-источнику внешний накопитель подходящего объёма (USB3-корпус с SSD/HDD или, если позволяет инфраструктура дата-центра, временный NVMe через адаптер).
  2. Скопируйте данные локально — это чтение с одного диска и запись на другой в пределах одного сервера, без сетевых накладных расходов:
   rsync -avh --stats /data/source/ /mnt/external-drive/
  1. Физически перенесите накопитель на сервер назначения — сами (если это возможно) или через услугу remote-hands у провайдера дата-центра.
  2. Подключите накопитель на новом сервере и скопируйте данные на целевой раздел таким же локальным rsync.
  3. После переноса основного объёма — сделайте финальную сетевую досинхронизацию дельты (см. следующий раздел), чтобы забрать файлы, изменившиеся за время физической перевозки.

Ограничения этого подхода стоит проговорить честно: он требует физического доступа к обоим серверам либо оплаченной услуги remote-hands, добавляет логистическое время (курьер или сотрудник дата-центра между стойками), и если данные чувствительные — накопитель для перевозки нужно шифровать (например, через LUKS), чтобы не создавать риск при физическом перемещении. Прежде чем выбирать этот вариант, стоит прогнать ту же тестовую методику из предыдущего раздела и сравнить: локальная скорость копирования на реальном оборудовании против измеренной сетевой — и принимать решение по цифрам, а не по интуиции.

Стратегия: перенос основного объёма заранее, в конце — только дельта

Главная практическая рекомендация всей статьи — не начинайте перенос данных в последнюю ночь перед переключением. Файловое хранилище на терабайты почти всегда можно и нужно начать переносить заранее, параллельно с остальной подготовкой миграции (настройкой нового сервера, DNS, приложений, тестами).

Последовательность, которая на практике сокращает окно простоя до минимума:

  1. Заранее, за дни или недели до переключения — запускаете первый, самый долгий проход rsync (с параллелизацией, без --delete, чтобы случайно не удалить что-то на источнике или назначении, если процесс прервётся). Это тот самый долгий перенос основного объёма — пусть он идёт в фоне, пока вы занимаетесь остальными частями миграции.
  2. Периодически, по мере готовности, повторяете тот же rsync — он по природе инкрементальный: файлы, которые не изменились, пропускаются, копируются только новые и изменившиеся. Каждый повторный проход намного быстрее первого.
  3. В финальное окно обслуживания — останавливаете запись на источник (либо переводите приложение в режим только для чтения) и делаете последний, короткий проход с --delete, чтобы синхронизировать также и файлы, которые были удалены на источнике за это время:
   rsync -avh --delete --stats /data/source/ user@newserver:/data/target/
  1. Проверяете контрольные объёмы (du -sh, количество файлов find | wc -l) на обеих сторонах, переключаете трафик на новый сервер.

Это именно та методика — перенести основной объём заранее и синхронизировать только дельту в конце, — которая описана и для миграции базы данных: там точно так же долгий первый снапшот идёт заранее, а в окно простоя переносится только изменившееся. Разница только в инструменте (rsync для файлов вместо логической/физической репликации для БД), принцип общий.

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

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Сколько параллельных потоков rsync оптимально?

Единой цифры нет — зависит от количества ядер CPU, скорости дисков на обеих сторонах и запаса канала. На практике стоит попробовать 4–8 и смотреть по загрузке диска и сети (iostat, iftop): если диск уже под 100% при 4 потоках — увеличивать их число бессмысленно.

Нужно ли сжатие (-z) для видеоархива?

Как правило нет — видео уже сжато кодеком, повторное сжатие почти не уменьшает объём передачи, а только нагружает CPU. Используйте -z для текстовых данных или исключайте видео и другие уже сжатые форматы через --skip-compress.

Что делать, если файлы меняются во время переноса (активная запись)?

Промежуточные проходы rsync без --delete безопасны — изменившийся файл будет скопирован повторно на следующем проходе. Финальный проход с --delete делайте только после остановки записи на источник или перевода приложения в режим чтения.

Можно ли совместить сетевой перенос и физическую перевозку диска?

Да, и часто это оптимально: основной объём — на внешний накопитель локально и физически, а после его подключения на новом сервере — досинхронизировать дельту изменившихся файлов уже по сети.

Что если канал между серверами реально медленнее заявленного и параллелизация не помогает?

Значит, узкое место не в количестве потоков, а в самом канале или в дисках. В этом случае оцените вариант с физической перевозкой диска (раздел выше) — он не зависит от качества сетевого канала между дата-центрами.

Обсудить статью, задать вопрос или начать новую тему

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

Перейти в сообщество →