[Bash] dd Schreib- und Lesegeschwindigkeit erhöhen

Freezedevil

Lieutenant
Registriert
Mai 2011
Beiträge
641
Hi,

ich hab mir vor kurzem ein Raspberry Pi gekauft und nutze deshalb "dd" um die SD-Karte zu sichern und unter Umständen wiederherzustellen.
- Betriebssystem ist OSX ML
- Um die Kommandos steht noch ein bisschen Script
- $devname hat die Form /dev/disk1 was unter Linux zB /dev/sdb entspricht)
Backup:
Code:
cat $devname | pv -rbeps $size | gzip -c | dd of=$filename bs=512
Dabei erreiche ich eine Geschwindigkeit von ca. 4 MB/s (beim Lesen einer Datei von einer Partition ca. 18 MB/s)

Restore:
Code:
gzip -dc $backup | pv -rbp | dd of=$devname bs=512
Dabei erreiche ich eine Geschwindigkeit von ca. 0,5 MB/s (beim Schreiben einer Datei auf eine Partition ca. 6 MB/s)
Sowohl die Wahl der Blockgröße als auch das Weglassen von gzip haben keinen Einfluss auf die Werte.

Long story short: Wenn ich raw auf die SD-Karte schreibe oder von ihr lese liegt die Performance weit unter der eigentlich möglichen Geschwindigkeit. Was kann ich dagegen tun?
 
Welche Werte hast du denn für die Blockgröße ausprobiert? Bei Flashspeichern nehme ich immer bs=4M.

Ansonsten sieht alles gut aus. Ich würde vielleicht beim Backup stat cat ebenfalls dd if=... nehmen und die letzte pipe durch > ersetzen. Aber das dürfte eigentlich keinen Einfluß auf die Performance haben..
 
Zuletzt bearbeitet:
Werte für bs: "keinen", 512, 1024, 4096, 4m, 100m
Hat null,garnichts geändert.

Ursprünglich hatte ich statt cat auch noch ein dd zum lesen, aber cat war dann ein bisschen kürzer und man möchte ja die Vielfalt wahren^^

Die letzte Pipe durch ein > zu ersetzen hat leider auch nichts gebracht.

Dennoch vielen Dank für den Hinweis zu später Stunde.
 
Freezedevil schrieb:
Dabei erreiche ich eine Geschwindigkeit von ca. 4 MB/s (beim Lesen einer Datei von einer Partition ca. 18 MB/s)
[...]
Dabei erreiche ich eine Geschwindigkeit von ca. 0,5 MB/s (beim Schreiben einer Datei auf eine Partition ca. 6 MB/s)

Damit waren schon Partitionen auf der SD-Karte gemeint, alles andere würde ja auch keinen Sinn ergeben ;).
Die Karte schafft also erwiesenermaßen im r/w 18/6 MB/s (das gleiche hat auch ein Laufwerkstesttool ausgespuckt)
 
cat ist kurz für concatenate, also Dateien zusammenzuhängen. Das ist für deine Zwecke falsch.
Eine Faustregel ist, sobald man cat mit nur einem Parameter aufruft, macht man es nicht richtig.
Würdest du auch "Die Vielfalt wahren" wollen, wenn du eine Schraube eindrehen willst und dann
einfach mal eine Zange nehmen?

dd (copy and convert files) ist das Tool der wahl hier und mit Programmen rumprobiern, die für
deinen Zweck nicht gedacht sind, hilft wohl kaum weiter.

Was dein Problem mit der Geschwindigkeit angeht, kann ich auch nur annehmen, dass das
Speichermedium einfach so langsam ist und du deshalb nichts weiter tun kannst.
 
Schonmal daran gedacht, dass der gzip die Daten nicht schneller komprimieren kann!?

Ansonsten würde ich auch nicht das Blockdevice sichern, sondern die Filesysteme, das ist nochmal effizienter.
 
Freezedevil schrieb:
Die Karte schafft also erwiesenermaßen im r/w 18/6 MB/s (das gleiche hat auch ein Laufwerkstesttool ausgespuckt)
Wo getestet? Wo sicherst du? Direkt auf dem Raspberry Pi? Der hat nur eine lahme CPU, die evtl. bremst. Vor allem wenn du dann noch gzip verwendest.
 
@asdfman Ich finde sehr wohl, dass cat für den Zweck eine Datei in die Pipe zu schreiben sowohl geeignet, als auch gedacht ist. Ich zitiere dazu kurz ein paar Stellen aus meiner man-page:
NAME
cat -- concatenate and print files
[...]
DESCRIPTION
The cat utility reads files sequentially, writing them to the standard output.
[...]
EXAMPLES
The command:

cat file1

will print the contents of file1 to the standard output.
Die Verwendung kann ja nicht so falsch sein, wenn sie in der man-page als Beispiel steht. Wie gesagt habe ich ursprünglich auch zum Lesen dd benutzt und das hat das Ergebnis in keiner Weise beeinflusst (ich hab es zur Sicherheit gestern Abend auch nochmal getestet)

@Sannyboy111985 Wie ich im Eingangspost bereits erwähnt habe, spielt es für die Geschwindigkeit keine Rolle ob ich gzip aus der Pipe nehme und somit auf die Komprimierung verzichte. Das hatte ich auch schonmal im Verdacht.
Was genau meinst du damit, es sei effizienter die Dateisysteme zu sichern? In wiefern ist das effizienter?

@all Das allgemeine Procedere ist, dass ich die Karte aus dem Pi nehme ins Macbook stecke und alles weitere dort passiert. Dort laufen dann die Scripts mit den erwähnten langsamen Geschwindigkeiten. Kopiere ich allerdings eine Datei auf die SD-Karte (Finder und dd liefern gleiche Geschwindigkeiten) wenn ein Filesystem drauf ist, schaffe ich die höheren Geschwindigkeiten. Das bedeutet doch, dass die Karte in der Lage ist "schnell" zu lesen und zu schreiben und es nur eine Frage der Parameter ist, denn das FS kann ja auch nicht zaubern, sondern nur die Daten intelligent schreiben.

Wie immer vielen Dank für alle Hinweise auch wenn leider noch nicht der entscheidende dabei war (falls es ihn überhaupt gibt, aber ich hoffe mal schon).
 
Das mit "ohne" gzip war nicht klar ersichtlich, hatte was gelesen von Pipe weglassen, hat sich mir aber nicht ganz erschlossen, daher einfach mal die Frage.

Dir ist aber bewusst, dass du beim arbeiten mit dem Device auf Read-Ahead bzw Caching der Daten verzichten musst. Ggf wird hier sogar Synchron geschrieben, so dass nicht mal ein Queuing stattfindet und die I/Os wirklich sequentiell abgearbeitet werden. Sowas erhöht einfach die Latenz.

Anonsten würde ich flashspeicher mit einer Blocksize von 4096 8192 oder 16384 Bearbeiten, da das wohl den physikalischen Clustern am nächsten kommt bzw ein vielfaches darstellt, gerade beim Schreiben relevant.

Wenn du das Filesystem sicherst, also nur die Daten, müssen auch nur die echten Datenblöcke kopiert werden. Das heißt wenn die SD-Karte nur zu 75% belegt ist auch nur 75% der Kapazität die verarbeitet werden muss.
Dazu sollte man noch die ersten Sektoren der Platte per DD sichern um auch den Grub oder sonstige Bootloader gesichert zu haben und die zunächst beim "restore" zurück dumpen.
 
Das letze mal als ich mit der Geschwindigkeit von dd gekämpft habe,
stellte sich heraus dass das Kartenlesegerät ne macke hatte :-(
 
Ich hab auch schonmal in diese Richtung gedacht nur den Bootloader und zusätzlich die Dateien zu sichern, da ich sonst jedes Mal mehrere GB Nullen verarbeite. Für den Bootloader und die Partitionstabelle muss ich ja nur die ersten 512 Byte des Blockdevice sichern. Das ist also leicht, aber wie sichere ich am besten die Dateien um sie dann auch leicht wiederherstellen zu können? Ich vermute mal, dass man das mit rsync bewerkstelligen kann, muss mich aber erst einlesen. Wenn mir jemand dazu nen heißen Tip geben kann bin ich nicht abgeneigt ihn zu hören. Ein Problem hierbei ist noch, dass ich unter OSX gar nicht alle verwendeten Dateisysteme mounten kann, wobei ich das sicher lösen kann, da fuse für sshfs eh schon intalliert ist.

Das war aber eigentlich der zweite Schritt, nachdem ich das Tempoproblem in den Griff bekommen habe. Auch wenn es für meinen Anwendungsfall also evtl. gar nicht mehr relevant ist, bin ich also nach wie vor an einer Lösung des Geschwindigkeitsproblems interessiert. Die Blockgröße von 4096 hab ich ja schon probiert, aber es natürlich möglich, dass es daran liegt, dass das Caching und Read-Ahead wegfällt.

@apt Wie hast du das festgestellt?
 
Hier mal ein Beispiel für rsync:

Code:
rsync --stats --numeric-ids -aAhHSP  /mnt/quelle/ /mnt/ziel/

Sollte alle Rechte, Hard-, Softlinks usw. abdecken. Wie du gesagt hast, musst du natrürlich das Dateisystem mounten können.

Mache meine Backups bzw. Festplattenwechsel auch immer so. Klappt einwandfrei.
 
Danke, ich hab mir vorhin auch mal das Manual durchgelesen und bin vorerst bei "-az" hängen geblieben. Ich schau mir nachher mal die zusätzlichen Parameter bei dir an. Momentan kämpfe ich aber gegen VirtualBox um die SD-Karte durchgeschleift zu bekommen, da ich nach einer kurzen Recherche zu dem Ergebnis gekommen bin, dass ich ext* Volumes unter OSX maximal read-only gemountet bekomme.
 
Freezedevil schrieb:
Die Verwendung kann ja nicht so falsch sein, wenn sie in der man-page als Beispiel steht. Wie gesagt habe ich ursprünglich auch zum Lesen dd benutzt und das hat das Ergebnis in keiner Weise beeinflusst (ich hab es zur Sicherheit gestern Abend auch nochmal getestet)

Ich habe keine Ahnung, warum so ein Bullshite in der Manpage steht,
aber statt cat a | b kann (und sollte) man immer auch b < a machen.
Das erzielt das Selbe und man hat einen Prozess gespart.
 
@Freezedevil so blöd sich das anhört, dadurch dass ich einen anderen verwendet habe. Ich wusste dass es schneller gehen muss. Also bin ich sollange durch die Firma gerannt bis ich ein Ersatzcardreader aufgetrieben habe.
 
Mh ok, die Möglichkeit hab ich jetzt nicht, dafür hab ich mich erstmal damit abgefunden und für meinen Einsatzzweck ist Vorgehensweise mit rsync sowieso besser. Genau da muss ich aber nochmal nachhaken.
Ich hab mir jetzt extra eine Ubuntu-VM installiert in der ich das Backup folgendermaßen anschmeiße
Code:
sudo rsync --stats --numeric-ids -aAhHSP /home/max/mnt/sdcard/ files/ 2>errorlog
(ohne sudo war der errorlog ziemlich voll weshalb ich das so mache)
Am Ende bekomme ich dann folgendes Ergebnis präsentiert
Code:
Number of files: 28343
Number of files transferred: 22551
Total file size: 678.73M bytes
Total transferred file size: 678.23M bytes
Literal data: 678.23M bytes
Matched data: 0 bytes
File list size: 710.67K
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 680.00M
Total bytes received: 449.07K

sent 680.00M bytes  received 449.07K bytes  2.51M bytes/sec
total size is 678.73M  speedup is 1.00
Der Output von "df -h /dev/sdb3" sagt mit aber, dass 1,1GB belegt sind. Außerdem hat er nur 22551 von 28343 Dateien kopiert. Warum und wie kommt diese Diskrepanz von Datenmengen zustande? Nur wegen den fehlenden Dateien?

Edit: Ist es realistisch zu glauben, dass das Hardlinks sind?
 
Zuletzt bearbeitet:
Zum einen dass, und zum anderen wird der wohl /dev /porc und /sys sowie ggf weitere Pseudo Filesysteme mit allen darin enthaltenden Daten nicht sichern.

mach mal ein 'find | wc -l' und dein 'du -ms' auf die drei genannten und schau mal was dabei raus kommt.
 
Zurück
Oben