почему rsync не выполняет дельта-перенос

У меня есть двоичный файл, который имеет около 77 МБ:

nupic@nupic-virtualbox:~/VboxSharedFolder/experiments/sync/exp2$ ls -lah src/ total 77M drwxrwx--- 1 root vboxsf 0 Jun 21 13:31 . drwxrwx--- 1 root vboxsf 4.0K Jun 21 16:21 .. -rwxrwx--- 1 root vboxsf 77M May 27 2014 binary.bin 

Я играл с rsync и это функция алгоритма дельта, чтобы увидеть, как он работает. Идея заключалась в том, чтобы сделать небольшие различия в двоичном файле и посмотреть, сколько данных было передано с использованием нескольких методов. Для этих целей я сделал очень простой скрипт:

 #!/bin/bash # rsync does not trnansfers delta over local by default sed 's%\x00\x00\x00\x20\x66\x74\x79\x70\x69\x73\x6f\x6d\x00\x00\x02\x00%\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11%' src/binary.bin > dst/binary.bin strace -f -e trace=read,write -o rw_rsync_local_default.log rsync -avcz --progress src/ dst/ # rsync -no-W should enables delta tranfer no matter if local or remote sed 's%\x00\x00\x00\x20\x66\x74\x79\x70\x69\x73\x6f\x6d\x00\x00\x02\x00%\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11%' src/binary.bin > dst/binary.bin strace -f -e trace=read,write -o rw_rsync_local_delta_enabled.log rsync --no-W -avcz --progress src/ dst/ # rsync trnansfers delta over network by default sed 's%\x00\x00\x00\x20\x66\x74\x79\x70\x69\x73\x6f\x6d\x00\x00\x02\x00%\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11%' src/binary.bin > dst/binary.bin strace -f -e trace=read,write -o rw_rsync_remote.log rsync -avcz -e "ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" --progress src/ nupic@localhost:/home/nupic/VboxSharedFolder/experiments/sync/exp2/dst/ # scp should transfers whole file not delta sed 's%\x00\x00\x00\x20\x66\x74\x79\x70\x69\x73\x6f\x6d\x00\x00\x02\x00%\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11%' src/binary.bin > dst/binary.bin strace -f -e trace=read,write -o rw_scp.log scp src/binary.bin nupic@localhost:/home/nupic/VboxSharedFolder/experiments/sync/exp2/dst/ # cp always transfers whole file not delta sed 's%\x00\x00\x00\x20\x66\x74\x79\x70\x69\x73\x6f\x6d\x00\x00\x02\x00%\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11%' src/binary.bin > dst/binary.bin strace -f -e trace=read,write -o rw_cp.log cp src/binary.bin dst/binary.bin 

Затем у меня есть следующий цикл для оценки результатов:

 for i in *.log; do echo $i; cat $i | grep write | awk 'BEGIN {FS="="}{ sum += $2} END {print sum/1024/1024 "MB"}'; echo "###########"; done 

Вот результаты:

 rw_cp.log 67.8075MB ########### rw_rsync_local_default.log 146.697MB ########### rw_rsync_local_delta_enabled.log 66.8765MB ########### rw_rsync_remote.log 0.0707941MB ########### rw_scp.log 136.048MB ########### 

Из этих пяти экспериментов мне ясно только два:

  1. cp пишет примерно столько же байтов, сколько размер исходного файла ( rw_cp.log ).
  2. rsync использует дельта-алгоритм, когда получатель удален (по сети) ( rw_rsync_remote.log )

И вот мне непонятные вещи:

  1. Почему при вызове rsync на src и dst на localhost записывается примерно в два раза по размеру исходного файла? ( rw_rsync_local_default.log )
  2. Почему опция --no-W для rsync не передает только дельта для src и dst на localhost как указано здесь, и почему она по-прежнему передает весь файл целиком? ( rw_rsync_local_delta_enabled.log )
  3. Бонус: Почему scp передает примерно два байта в качестве исходного размера файла? Я понимаю, что есть некоторое шифрование, но два раза мне кажется большим ( rw_scp.log ).

2 Solutions collect form web for “почему rsync не выполняет дельта-перенос”

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

Мы можем это рассказать, более подробно рассмотрев вывод strace , идентификаторы процессов в начале файла, а также номера дескрипторов файла в вызовах write можно использовать, чтобы отличать разные «потоки» записи друг от друга.

Предположительно, это так, что локальная передача может работать так же, как удаленная передача, только источник и пункт назначения находятся в одной и той же системе.


Используя что-то вроде strace -e trace=process,socketpair,open,read,write будут отображаться некоторые потоки, создаваемые между ними, и разные потоки, открывающие входные и выходные файлы.

Тестирование аналогично вашему:

 $ rm test2 $ strace -f -e trace=process,socketpair,open,close,dup,dup2,read,write -o rsync.log rsync -avcz --progress test1 test2 $ ls -l test1 test2 -rw-r--r-- 1 itvirta itvirta 81920004 Jun 21 20:20 test1 -rw-r--r-- 1 itvirta itvirta 81920004 Jun 21 20:20 test2 

Давайте возьмем количество байтов, написанных для каждого потока отдельно:

 $ for x in 15007 15008 15009 ; do echo -en "$x: " ; grep -E "$x (<... )?write" rsync.log | awk 'BEGIN {FS=" = "} {sum += $2} END {print sum}' ; done 15007: 81967265 15008: 49 15009: 81920056 

Это в значительной степени соответствует приведенной выше теории. Я не проверял, что другой 40kB, написанный первым потоком, но я предполагаю, что он печатает результат выполнения, и любые метаданные о синхронизируемом файле rsync необходимо перенести на другой конец.


Я не проверял, но я предполагаю, что даже при включенном дельта-сжатии, возможно, «удаленный» конец rsync все еще записывает (большую часть) файл в полном объеме, в результате получается примерно такое же количество записей, что и в cp. Передача между потоками rsync меньше, но конечный вывод все тот же.

По умолчанию rsync сначала создает новую копию целевого файла, а затем заменяет его по различным причинам безопасности. Вы можете переопределить это, указав --inplace вместе с --no-whole-file . Это говорит rsync, чтобы сделать редактирование целевого файла на месте, принимая различные риски (как правило, незначительные для этой ситуации), как описано на странице руководства.

  • «Не обычный файл» при попытке просмотреть файл .gitignore
  • Проблемы с scp, если я использую bashrc для открытия рыбы, если она присутствует
  • Как загрузить файл с хоста, к которому я уже подключен, поверх ssh
  • Ошибка при использовании rsync и scp
  • Почему эта команда scp создает каталог на один уровень вверх?
  • Скопируйте и получите файлы с одной машины, которая связана через ssh с другим
  • Я не могу скопировать удаленный файл с помощью scp, но я могу войти в систему, используя ssh
  • разрешение scp отказано после «затвердения» с помощью бастилии
  • не удалось использовать scoply для операции scp
  • указать оболочку для сеанса ssh
  • SCP воспроизводит разрыв трубки SSH
  • Linux и Unix - лучшая ОС в мире.