rsync가 증분 전송을 수행하지 않는 이유

rsync가 증분 전송을 수행하지 않는 이유

약 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

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. rsyncBoth srcdston localhostwrite에 대한 호출이 원래 파일 크기(바이트)의 약 두 배인 이유는 무엇입니까 ? ( rw_rsync_local_default.log)
  2. --no-W옵션이 지정된 rsync대로 src델타 만 전송하지 않는 이유dstlocalhost여기왜 여전히 전체 파일을 전송하고 있습니까? ( rw_rsync_local_delta_enabled.log)
  3. 보너스 팁: scp전송된 바이트 수가 원래 파일 크기의 약 두 배인 이유는 무엇입니까? 일부 암호화가 있다는 것을 알고 있지만 두 번은 나에게 큰 문제처럼 보입니다( rw_scp.log).

답변1

간단히 말해서, 주요 질문에 답하기 위해 rsync복사를 수행하기 위해 두 개의 프로세스/스레드를 생성하고 프로세스 사이에 하나의 스트리밍 데이터가 있고 수신 프로세스에서 대상 문서로 다른 스트리밍 데이터가 있기 때문에 바이트 수를 두 배로 쓰는 것 같습니다.

출력을 더 자세히 보면 strace이를 알 수 있습니다. 파일 시작 부분의 프로세스 ID와 호출의 파일 설명자 번호를 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 스레드 간의 전송은 더 작지만 최종 출력은 여전히 ​​동일합니다.

답변2

기본적으로 다양한 보안상의 이유로 rsync는 먼저 대상 파일의 새 복사본을 만든 다음 이를 바꿉니다. --inplace및 를 지정하여 이를 재정의 할 수 있습니다 --no-whole-file. 이는 rsync가 대상 파일의 내부 편집을 수행하고 매뉴얼 페이지에 문서화된 다양한 위험(이 경우 일반적으로 사소한 위험)을 수용하도록 지시합니다.

관련 정보