Das Schreiben in einen Unterordner ist schneller als das Schreiben in den übergeordneten Ordner.

Das Schreiben in einen Unterordner ist schneller als das Schreiben in den übergeordneten Ordner.

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 emzed2entstand 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/testfilewird in der (wahrscheinlich stark belasteten) Stammblockgruppe erstellt, während in der (wahrscheinlich leeren) Blockgruppe /data/emzed2/testfileerstellt 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/testfilewird das Dateisystem zuerst alle Datenblöcke in der emzed2Blockgruppe zuordnen. Wenn dieser Block anfangs leer war, bedeutet dies für die ersten 128 MB überhaupt keine Fragmentierung. Bei /data/testfilewird 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.

verwandte Informationen