Nehmen wir an, wir verwenden ext4 (mit aktiviertem dir_index) zum Hosten von etwa 3 Millionen Dateien (mit einer durchschnittlichen Größe von 750 KB) und müssen uns entscheiden, welches Ordnerschema wir verwenden.
In der ersten Lösung wenden wir eine Hash-Funktion auf die Datei an und verwenden einen Ordner mit zwei Ebenen (1 Zeichen für die erste Ebene und 2 Zeichen für die zweite Ebene). Da der filex.for
Hash also abcde1234 entspricht, speichern wir ihn in / path / a / bc /abcde1234-filex.for.
In der zweiten Lösung wenden wir eine Hash-Funktion auf die Datei an und verwenden einen Ordner mit zwei Ebenen (bestehend aus 2 Zeichen für die erste Ebene und 2 Zeichen für die zweite Ebene). Wenn der filex.for
Hash also gleich abcde1234 ist , speichern wir ihn in / path / ab / de /abcde1234-filex.for.
Für die erste Lösung haben wir das folgende Schema /path/[16 folders]/[256 folders]
mit durchschnittlich 732 Dateien pro Ordner (der letzte Ordner, in dem sich die Datei befinden wird).
Während auf der zweiten Lösung werden wir haben /path/[256 folders]/[256 folders]
mit einem Durchschnitt von 45 Dateien pro Ordner .
In Anbetracht dessen, dass wir von diesem Schema aus viele Dateien schreiben / trennen / lesen ( aber meistens lesen ) (im Grunde genommen das Nginx-Caching-System), ist es in Bezug auf die Leistung von Bedeutung, ob wir die eine oder andere Lösung gewählt haben?
Mit welchen Tools können wir dieses Setup überprüfen / testen?
quelle
hdparm -Tt /dev/hdX
aber es ist möglicherweise nicht das am besten geeignete Tool.hdparm
ist nicht das richtige Tool, es ist eine Überprüfung der unformatierten Leistung des Blockgeräts und kein Test des Dateisystems.Antworten:
Der Grund für die Erstellung einer solchen Verzeichnisstruktur ist, dass Dateisysteme eine Datei in einem Verzeichnis suchen müssen. Je größer das Verzeichnis ist, desto langsamer ist diese Operation.
Wie viel langsamer, hängt vom Dateisystemdesign ab.
Das ext4-Dateisystem verwendet einen B-Baum zum Speichern von Verzeichniseinträgen. Es wird erwartet, dass eine Suche in dieser Tabelle eine Zeit von 0 (log n) benötigt. Dies ist in den meisten Fällen weniger als in der naiven linearen Tabelle, die ext3 und frühere Dateisysteme verwendet haben (und wenn dies nicht der Fall ist, ist das Verzeichnis zu klein, um dies zu tun) wirklich wichtig).
Das XFS-Dateisystem verwendet stattdessen einen B + -Baum . Dies hat gegenüber einer Hash-Tabelle oder einem B-Baum den Vorteil, dass jeder Knoten mehrere untergeordnete Knoten b haben kann , wobei XFS b unterschiedlich ist und bis zu 254 (oder 19 für den Stammknoten) betragen kann. Diese Nummern sind möglicherweise veraltet ). Dies gibt Ihnen eine zeitliche Komplexität von O (log b n) , eine enorme Verbesserung.
Jedes dieser Dateisysteme kann Zehntausende von Dateien in einem einzigen Verzeichnis verarbeiten, wobei XFS in einem Verzeichnis mit der gleichen Anzahl von Inodes erheblich schneller ist als ext4. Aber Sie möchten wahrscheinlich kein einziges Verzeichnis mit 3M-Inodes, da die Suche selbst bei einem B + -Baum einige Zeit in Anspruch nehmen kann. Dies hat in erster Linie dazu geführt, dass Verzeichnisse auf diese Weise erstellt wurden.
Die erste Option, die Sie für Ihre vorgeschlagenen Strukturen angegeben haben, ist genau das, was in nginx-Beispielen gezeigt wird. Es funktioniert auf beiden Dateisystemen gut, obwohl XFS immer noch einen gewissen Vorteil bietet. Die zweite Option kann etwas besser oder etwas schlechter abschneiden, wird aber wahrscheinlich auch bei Benchmarks ziemlich knapp sein.
quelle
ls -l
dauert eine ganze Minute, wenn das Verzeichnis aus dem Inode-Cache entfernt wurde. Und wenn es zwischengespeichert wird, dauert es immer noch über eine Sekunde. Dies ist mit einer SSD und einem Xeon mit Tonnen von RAM auf einem ziemlich verkehrsarmen Webserver.Nach meiner Erfahrung ist einer der Skalierungsfaktoren die Größe der Inodes bei einer Partitionierungsstrategie für Hash-Namen.
Beide von Ihnen vorgeschlagenen Optionen erstellen bis zu drei Inode-Einträge für jede erstellte Datei. Außerdem erzeugen 732-Dateien einen Inode, der immer noch kleiner als die üblichen 16 KB ist. Für mich bedeutet dies, dass beide Optionen die gleiche Leistung erbringen.
Ich begrüße Sie für Ihren kurzen Haschisch. Bei früheren Systemen, an denen ich gearbeitet habe, wurde die Summe der angegebenen Dateien und der gespleißten Verzeichnisse basierend auf dieser Zeichenfolge verwendet. Dies ist ein weitaus schwierigeres Problem.
quelle
Mit beiden Optionen können Sie die Anzahl der Dateien in einem Verzeichnis auf einen Wert reduzieren, der für xfs, ext4 oder ein anderes Dateisystem als sinnvoll erscheint. Es ist nicht klar, was besser ist, müsste testen, um zu sagen.
Ein Benchmark mit Ihrer Anwendung, die so etwas wie die tatsächliche Arbeitslast simuliert, ist ideal. Andernfalls lassen Sie sich etwas einfallen, das viele kleine Dateien speziell simuliert. Apropos, hier ist eine Open-Source-Datei namens Smallfile . Die Dokumentation verweist auf einige andere Tools.
hdparm
Dauerhafte E / A-Vorgänge sind weniger nützlich. Es werden nicht die vielen kleinen E / A-Vorgänge oder riesigen Verzeichniseinträge angezeigt, die mit sehr vielen Dateien verknüpft sind.quelle
Eines der Probleme ist die Möglichkeit, den Ordner zu scannen.
Stellen Sie sich eine Java-Methode vor, die einen Scan für den Ordner ausführt.
Es muss eine große Menge an Speicher reservieren und diese in kurzer Zeit freigeben, was für die JVM sehr schwer ist.
Am besten ordnen Sie die Ordnerstruktur so an, dass sich jede Datei in einem bestimmten Ordner befindet, z. B. Jahr / Monat / Tag.
Bei einem vollständigen Scan wird für jeden Ordner eine Ausführung der Funktion ausgeführt, sodass JVM die Funktion beendet, den Arbeitsspeicher freigibt und ihn erneut für einen anderen Ordner ausführt.
Dies ist nur ein Beispiel, aber es macht sowieso keinen Sinn, solch einen riesigen Ordner zu haben.
quelle
Ich habe das gleiche Problem gehabt. Versucht, Millionen von Dateien auf einem Ubuntu-Server in ext4 zu speichern. Ich habe damit aufgehört, meine eigenen Benchmarks zu erstellen. Stellen Sie fest, dass Flat Directory eine bessere Leistung erbringt und gleichzeitig einfacher zu bedienen ist:
Schrieb einen Artikel .
quelle