Ich habe eine Binärdatei mit ca. 77 MB:
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
Ich habe mit gespielt rsync
und es ist eine Delta-Algorithmus-Funktion, um zu sehen, wie es funktioniert. Die Idee war, kleine Unterschiede in der Binärdatei zu machen und zu sehen, wie viele Daten mit verschiedenen Methoden übertragen wurden. Für diese Zwecke habe ich ein sehr einfaches Skript erstellt:
#!/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
Dann habe ich folgende Schleife zur Auswertung der Ergebnisse:
for i in *.log; do
echo $i; cat $i | grep write | awk 'BEGIN {FS="="}{ sum += $2} END {print sum/1024/1024 "MB"}';
echo "###########";
done
Hier sind die Ergebnisse:
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
###########
Von diesen fünf Experimenten sind mir nur zwei klar:
cp
schreibt ungefähr die gleiche Anzahl von Bytes wie die Größe der Originaldatei (rw_cp.log
).rsync
Verwendet den Delta-Algorithmus, wenn das Ziel entfernt ist (über das Netzwerk) (rw_rsync_remote.log
)
Und hier sind mir unklare Dinge:
- Warum beim Aufrufen
rsync
von beidensrc
unddst
beimlocalhost
Schreiben werden ungefähr zwei Bytes so groß wie die Originaldatei geschrieben? (rw_rsync_local_default.log
) - Warum überträgt die
--no-W
Option fürrsync
nicht nur Delta fürsrc
unddst
weiter,localhost
wie hier angegeben , und warum überträgt sie immer noch ungefähr die gesamte Datei? (rw_rsync_local_delta_enabled.log
) - Bonus: Warum werden
scp
ungefähr doppelt Bytes als ursprüngliche Dateigröße übertragen? Ich verstehe, dass es eine Verschlüsselung gibt, aber zweimal scheint mir groß (rw_scp.log
).
scp
wird ein untergeordneterssh
Prozess erstellt, um das eigentliche SSH-Protokoll (Handshake, Verschlüsselung und MAC) auszuführen. Auf diese Weise liest der Elternteil die Datei und schreibt über die Pipe in das Kind und schreibt auch die Fortschrittsanzeige in das Terminal, das ziemlich klein ist. Das Kind liest die Pipe und liest und schreibt den Socket für das SSH-Protokoll, wodurch normalerweise 1-2 KB Start und möglicherweise 1% zu den Daten hinzugefügt werden.for x in $(awk '{print $1}' rsync.log | sort | uniq); do; echo -en "$x: "; grep -E "$x (<... )?write" rsync.log | awk 'BEGIN {FS=" = "} {sum += $2} END {print sum}'; done
Standardmäßig erstellt rsync zuerst eine neue Kopie der Zieldatei und ersetzt sie dann aus verschiedenen Sicherheitsgründen. Sie können dies überschreiben, indem Sie
--inplace
zusammen mit angeben--no-whole-file
. Dadurch wird rsync angewiesen, die Zieldatei direkt zu bearbeiten und dabei die verschiedenen (in dieser Situation normalerweise geringfügigen) Risiken zu akzeptieren, die in der Manpage dokumentiert sind.quelle