porque o rsync não faz transferência delta

7

Eu tenho um arquivo binário que tem aproximadamente 77MB:

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

Eu tenho jogado com rsync e seu recurso de algoritmo delta para ver como ele está funcionando. A idéia era fazer pequenas diferenças no arquivo binário e ver quantos dados foram transferidos usando vários métodos. Para esses propósitos, criei um script muito simples:

#!/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

Então eu tenho o seguinte loop para avaliação dos resultados:

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

Aqui estão os resultados:

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
###########

A partir desses cinco experimentos, apenas dois são claros para mim:

  1. cp escreve aproximadamente a mesma quantidade de bytes que o tamanho do original arquivo ( rw_cp.log ).
  2. rsync usa o algoritmo delta quando o destino é remoto (pela rede) ( rw_rsync_remote.log )

E aqui não estão claras as coisas para mim:

  1. Por que invocar rsync em src e dst on localhost escreve aproximadamente duas vezes bytes como o tamanho do arquivo original? ( rw_rsync_local_default.log )
  2. Por que a opção --no-W para rsync não transfere apenas delta para src e dst on localhost como declarado aqui e por que ainda transfere o arquivo inteiro aproximadamente? ( rw_rsync_local_delta_enabled.log )
  3. Bônus: Por que scp transfere aproximadamente duas vezes bytes como tamanho de arquivo original? Eu entendo que há alguma criptografia, mas duas vezes parece grande para mim ( rw_scp.log ).
por Wakan Tanka 21.06.2016 / 17:27

2 respostas

4

Para responder a questão principal em resumo, rsync parece escrever o dobro do número de bytes, porque gera dois processos / threads para fazer a cópia, e há um fluxo de dados entre os processos e outro do processo de recebimento para o arquivo de destino.

Podemos dizer isso observando a strace output em mais detalhes, os IDs do processo no início do arquivo e também os números do descritor de arquivo nas chamadas write podem ser usados para informar fluxos de gravação diferentes "um do outro.

Presumivelmente, isso é para que uma transferência local funcione como uma transferência remota, somente a origem e o destino estão no mesmo sistema.

Usar algo como strace -e trace=process,socketpair,open,read,write mostraria alguns tópicos gerados, o par de soquetes sendo criado entre eles e diferentes segmentos abrindo os arquivos de entrada e saída.

Um teste semelhante ao seu:

$ 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

Vamos considerar uma contagem de bytes escritos para cada thread separadamente:

$ 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

Que combina bastante com a teoria acima. Eu não verifiquei o que os outros 40kB escritos pelo primeiro thread é, mas eu assumirei que ele imprime a saída do progresso, e quaisquer metadados sobre o arquivo sincronizado que o rsync precisa transferir para o outro lado.

Eu não verifiquei, mas sugiro que, mesmo com a compactação delta ativada, talvez o final "remoto" do rsync ainda grave (a maior parte) o arquivo inteiro, resultando na mesma quantidade de gravações que com cp. A transferência entre os encadeamentos rsync é menor, mas a saída final ainda é a mesma.

    
por 21.06.2016 / 20:03
1

Por padrão, o rsync primeiro cria uma nova cópia do arquivo de destino e o substitui por vários motivos de segurança. Você pode substituir isso especificando --inplace junto com --no-whole-file . Isso diz ao rsync para fazer uma edição no local do arquivo de destino, aceitando os vários riscos (geralmente menores para essa situação) conforme documentado na página man.

    
por 20.09.2017 / 17:38

Tags