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

この5つの実験では、私には2つのことが明らかになりました。

  1. cp書き込んだバイト数は、元のファイルのサイズ(rw_cp.log)とほぼ同じです。
  2. rsyncターゲットがリモート(ネットワーク経由)の場合は、増分アルゴリズム(rw_rsync_remote.log)を使用してください。

私にとって不明な内容は次のとおりです。

  1. rsyncBothsrcdston localhostwriteの呼び出しが元のファイルサイズ(バイト)の約2倍になるのはなぜですか? ( rw_rsync_local_default.log)
  2. --no-Wオプションが指定されたrsyncようにsrcデルタだけを送信しない理由dstlocalhostここなぜまだファイル全体を転送していますか? ( rw_rsync_local_delta_enabled.log)
  3. ボーナスのヒント:scp送信されたバイト数が元のファイルサイズの約2倍であるのはなぜですか?いくつかの暗号化があることを知っていますが、2回は私にとって大きな問題のようです(rw_scp.log)。

ベストアンサー1

簡単に言えば、主要な質問に答えるrsyncためにコピーを実行するために2つのプロセス/スレッドを作成し、プロセス間に1つのストリーミングデータがあり、受信プロセスからターゲット文書に異なるストリーミングデータがあるため、バイト数を2倍にするようです。

出力をさらに詳しく見ると、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スレッド間の転送は小さいですが、最終出力は依然として同じです。

おすすめ記事