Ich verwende dd, um die Schreibleistung zu messen, und habe etwas Seltsames beobachtet: Das Schreiben in /data/emzed2 ist schneller als das Schreiben in /data. So habe ich die Leistung gemessen:
$ dd wenn=/dev/nullvon=/data/emzed2/testfilebs=32
^C4921834+0 Datensätze in
4921834+0 Datensätze aus 157498688 Bytes (157 MB) kopiert, 2,87329 s,54,8 MB/s
$ dd wenn=/dev/nullvon=/Daten/Testdateibs=32
^C2487991+0 Datensätze in
2487991+0 Datensätze aus 79615712 Bytes (80 MB) kopiert, 2,6501 s,Geschwindigkeit
beide Ordner befinden sich auf derselben Partition auf einem SSD-Laufwerk. Ich verwende Ubuntu 14.04 und habe das Experiment mehrmals mit ähnlichen Ergebnissen wiederholt.
Irgendeine Idee, was los ist?
Antwort1
Es scheint, dass Sie von ext4-Optimierungen betroffen sindEinige davon sind beschrieben inExt4-FestplattenlayoutDokumentation.
Jedes Mal, wenn Sie eine Datei vergrößern, beispielsweise mit dd, wird ein Platz für die neuen Daten reserviert. Schließlich könnte die Datei fragmentiert werden, d. h. die Daten könnten in mehreren Blöcken über die Festplatte verteilt werden. Fragmentierung ist eine bekannte Ursache für Langsamkeit (beim Lesen und Schreiben) und daher versuchen Dateisystemimplementierungen häufig, sie zu vermeiden. Fragmentierung ist bei rotierenden Festplatten (der Kopf muss zu aufeinanderfolgenden Blöcken wandern) viel kostspieliger als bei SSD, dennoch verwenden die meisten Dateisystemimplementierungen für rotierende Festplatten optimierte Strategien mit SSD.
Eine Kombination aus dem dritten, vierten und fünften "Trick", der in der oben genannten Dokumentation beschrieben wirdkönnteErklären Sie, warum das Schreiben in das Unterverzeichnis in Ihrem Fall schneller ist.
Der fünfte Trick besteht darin, dass das Datenträgervolumen in 128 MB große Blockgruppen aufgeteilt wird. […] Wenn im Stammverzeichnis ein Verzeichnis erstellt wird, durchsucht der Inode-Allocator die Blockgruppen und fügt dieses Verzeichnis der am wenigsten ausgelasteten Blockgruppe hinzu, die er finden kann.
Als Ergebnis emzed2
entstand vermutlich ein leerer Block von 128MB.
Der vierte Trick besteht darin, alle Inodes in einem Verzeichnis, wenn möglich, in derselben Blockgruppe wie das Verzeichnis zu platzieren.
Folglich /data/testfile
wird in der (wahrscheinlich stark belasteten) Stammblockgruppe erstellt, während in der (wahrscheinlich leeren) Blockgruppe /data/emzed2/testfile
erstellt wird .emzed2
Der dritte Trick […] besteht darin, dass versucht wird, die Datenblöcke einer Datei in derselben Blockgruppe wie ihren Inode zu halten.
Bei /data/emzed2/testfile
wird das Dateisystem zuerst alle Datenblöcke in der emzed2
Blockgruppe zuordnen. Wenn dieser Block anfangs leer war, bedeutet dies für die ersten 128 MB überhaupt keine Fragmentierung. Bei /data/testfile
wird das Dateisystem zuerst die Stammblockgruppe füllen, wenn sie noch nicht gefüllt war, und dann nach anderen Orten zum Speichern von Daten suchen.
Außerdem vergrößern Sie die Datei jeweils um 32 Bytes. Glücklicherweise weisen Dateisysteme wie ext4 mehr Daten zu, als Sie anfordern (im Fall von ext4 in 8-KB-Blöcken) und versuchen, die Zuweisung zu verzögern. Sie würden wahrscheinlich ein ähnliches Muster mit sehen bs=8196
, aber der Geschwindigkeitsunterschied könnte bei größeren Blockgrößen geringer werden.