Последнюю пару лет я переносил со службы домой и обратно «набор рабочих материалов» — видеофайлы и данные проектов, пользуясь внешним SSD-диском стандарта NVMe с интерфейсом Thunderbolt.

Но, когда я синхронизировал данные, это всегда происходило очень медленно. В обычный рабочий день я могу создать новую папку проекта, содержащую 500-1000 файлов. При этом среди них будут дюжины файлов размером 1–10 Гб.

Мой Thunderbolt-диск способен передавать данные со скоростью, значительно превышающей 5 Гб/с, а 10-гигабитное сетевое соединение, имеющееся в моём распоряжении, может выдать 1 Гб в секунду. Недавно я даже обновил диск до Thunderbolt 5, хотя его и нельзя назвать узким местом моей системы.

Я использовал команду rsync следующего вида для копирования файлов с общего сетевого ресурса, смонтированного на моём Mac, на диск, которому я дал имя Shuttle:

rsync -au --progress --stats /Volumes/mercury/* /Volumes/Shuttle/Video_Projects

Ресурс mercury назван именно так из-за того, что он представляет собой быстрый том, базирующийся на NVMe-диске, размещённом на моём NAS (Network-attached Storage, сетевое хранилище данных). Моё сетевое хранилище основано на архитектуре Arm, а все сетевые тома я называю в честь небесных тел.

Я, в качестве теста, удалил один из примерно дюжины активных проектов с диска Shuttle и запустил копирование данных с помощью rsync:

$ time rsync -au --progress --stats /Volumes/mercury/* /Volumes/Shuttle/Video_Projects
Radxa Orion O6/
Radxa Orion O6/.DS_Store
           6148 100%    4.80MB/s   00:00:00 (xfer#1, to-check=1582/3564)
Radxa Orion O6/Micro Center Visit Details.pages
         141560 100%    9.83MB/s   00:00:00 (xfer#2, to-check=1583/3564)
Radxa Orion O6/Radxa Orion O6.md
          19817 100%    1.89MB/s   00:00:00 (xfer#3, to-check=1584/3564)
Radxa Orion O6/BIOS and Images/
Radxa Orion O6/BIOS and Images/orion-o6-bios-0.2.2-1.zip
        3916964 100%   83.32MB/s   00:00:00 (xfer#4, to-check=1586/3564)
Radxa Orion O6/BIOS and Images/orion-o6-bios-9.0.0-apr-11.7z
        4341505 100%  112.62MB/s   00:00:00 (xfer#5, to-check=1587/3564)
Radxa Orion O6/Scratch/
Radxa Orion O6/Scratch/bios 9.0.0 - screen acpi and debian 12 attempt.mp4
      254240026 100%  114.11MB/s   00:00:02 (xfer#6, to-check=1589/3564)
...
Number of files: 3564
Number of files transferred: 122
Total file size: 244284287846 B
Total transferred file size: 62947785101 B
Unmatched data: 62947785101 B
Matched data: 0 B
File list size: 444318 B
File list generation time: 9.155 seconds
File list transfer time: 0.078 seconds
Total sent: 62955918871 B
Total received: 2728 B

sent 62955918871 bytes  received 2728 bytes  128990035 bytes/sec
total size is 244284287846  speedup is 3.88

real    8:17.57
user    3:13.14
sys 2:45.45

Создание полной копии данных заняло около 8 минут, всего было скопировано около 59 ГиБ файлов. Тут имеются две проблемы:

  • Команда rsync копирует данные в однопоточном режиме, последовательно, то есть — в некий момент времени копируется только один файл.

  • Даже копируя очень большие файлы rsync, похоже, при работе с этим сетевым ресурсом, выходит на максимальную скорость около 350 Мб/с.

Я поэкспериментировал с разными алгоритмами сжатия, пытался сначала задействовать tar, а потом передавать rsync то, что получилось. Я даже пробовал запускать демон rsync вместо использования SSH… Но у меня ни разу не получалось значительно ускорить копирование! На самом деле, применение некоторых режимов сжатия даже замедляло работу, так как мой энергоэффективный NAS работает на достаточно медленных Arm-ядрах, что приводит к некоторому замедлению однопоточных программ.

Команда rclone приходит на помощь

Я многие годы использую команду rclone, которая является частью моей стратегии резервного копирования «3-2-1». Эта команда замечательно копирует, перемещает, синхронизирует файлы, работая практически с любыми хранилищами (включая облачные хранилища данных, локальные хранилища, NAS-тома и так далее). А я, уж не знаю почему, навесил на неё ярлык инструмента, который предназначен для переноса данных из локального хранилища в облако и обратно. Я никогда не рассматривал rclone в роли команды, пригодной для локального переноса файлов, скажем — для работы с файлами в моей собственной LAN.

А у этой команды есть опция, которая позволяет организовать параллельную работу с файлами: --multi-thread-streams. Применить её для решения похожих задач предложил кому-то пользователь Stack Overflow dantebarba.

Я решил эту опцию попробовать.

После некоторой возни с подбором точных параметров, соответствующих параметру -a команды rsync, после решения вопросов со странными символическими ссылками, вроде директорий .fcpcache, которые Final Cut Pro запихивает в проекты, я создал следующую конструкцию:

rclone sync \
  --exclude='**/._*' \
  --exclude='.fcpcache/**' \
  --multi-thread-streams=32 \
  -P -L --metadata \
  /Volumes/mercury/ /Volumes/Shuttle/Video_Projects

Применяя новый метод, я обнаружил, что сетевое соединение моего Mac быстро вышло на максимальную скорость передачи данных, находящуюся в районе 1 Гб/с. Копирование той же директории, что и раньше, заняло 2 минуты:

$ rclone sync \                                                                       
  --exclude='**/._*' \
  --exclude='.fcpcache/**' \
  --multi-thread-streams=32 \
  --progress --links --metadata \
  /Volumes/mercury/ /Volumes/Shuttle/Video_Projects
2025/05/06 12:03:57 NOTICE: Config file "/Users/jgeerling/.config/rclone/rclone.conf" not found - using defaults
Transferred:       58.625 GiB / 58.625 GiB, 100%, 0 B/s, ETA -
Checks:              2503 / 2503, 100%
Transferred:          122 / 122, 100%
Server Side Copies:   122 @ 58.625 GiB
Elapsed time:      2m15.3s

Мне не совсем понятно, почему rclone сообщает о копировании 59 Гб, а rsync — о 63 Гб. Может — это из-за исключения папки .fcpcache? Ох, насмешил — дело в единицах измерения — я пытался сравнивать GiB (ГиБ, гибибайты) и GB (Гб, гигабайты) ;).

Тут, в любом случае, у меня напрашивается следующий вывод, особенно после того, как я понаблюдал за полной загрузкой 10-гигабитного соединения: rclone, при работе в параллельном режиме, примерно в 4 раза быстрее rsync.

Ещё я провёл сравнения команд, просто заменив несколько файлов. Оказалось, что rclone и rsync работают с почти одинаковой скоростью, так как полное сканирование дерева каталогов в поиске изменений метаданных занимает и у одной, и у другой команды примерно одно и то же время (около 18 секунд). Команда rclone выходит в лидеры только благодаря возможностям по параллельной передаче файлов.

О, а приходите к нам работать? ? ?

Мы в wunderfund.io занимаемся высокочастотной алготорговлей с 2014 года. Высокочастотная торговля — это непрерывное соревнование лучших программистов и математиков всего мира. Присоединившись к нам, вы станете частью этой увлекательной схватки.

Мы предлагаем интересные и сложные задачи по анализу данных и low latency разработке для увлеченных исследователей и программистов. Гибкий график и никакой бюрократии, решения быстро принимаются и воплощаются в жизнь.

Сейчас мы ищем плюсовиков, питонистов, дата-инженеров и мл-рисерчеров.

Присоединяйтесь к нашей команде

Комментарии (9)


  1. Ryav
    09.06.2025 09:52

    Интересно, почему в rsync не добавили подобный функционал, напрашивается же.


    1. Lx6g1ZG1
      09.06.2025 09:52

      Можно как-то так: (используя parallel в 4 потока):
      # find /source/dir -type f | parallel -j4 rsync -R {} user@remote:/destination


      1. andreymal
        09.06.2025 09:52

        Поздравляю, вы не только сломали синхронизацию свойств каталогов и опции вроде --delay-updates или --delete-after, но и убили производительность постоянными переподключениями SSH-соединений (а ещё такая команда всё равно не работает, потому что parallel не умеет читать из stdin)

        Слепое следование идеологиям ни к чему хорошему не приводит


        1. Lx6g1ZG1
          09.06.2025 09:52

          это пример...приведите свой, который вам кажется лучшим.
          Хотел показать что можно параллельно запускать задачи копирования используя rsync.


          1. andreymal
            09.06.2025 09:52

            Так вся эта статья посвящена этому самому примеру — rclone


            1. Lx6g1ZG1
              09.06.2025 09:52

              автор пишет в завершении статьи:


              Команда rclone выходит в лидеры только благодаря возможностям по параллельной передаче файлов.


              я привел пример что распараллеливание возможно и в случае с rsync. Про производительность ничего не говорил.


              1. andreymal
                09.06.2025 09:52

                Тогда в вашем примере тем более нет смысла


                1. Lx6g1ZG1
                  09.06.2025 09:52

                  однако вы его прокоментировали зачем-то


  1. Lx6g1ZG1
    09.06.2025 09:52

    По идеологии Unix каждая программа выполняет одну свою функцию. В случае с rsync — копирование в одном потоке, а распараллеливание можно реализовать с помощью других инструментов (например, xargs, parallel).