Linux: Wie viele Festplatten-E / A werden zum Lesen einer Datei benötigt? Wie kann man es minimieren? [Duplikat]

10

Laut diesem Artikel auf Facebooks Haystack:

" Aufgrund der Art und Weise, wie die NAS-Appliances Verzeichnismetadaten verwalten, war das Platzieren von Tausenden von Dateien in einem Verzeichnis äußerst ineffizient, da die Blockmap des Verzeichnisses zu groß war, um von der Appliance effektiv zwischengespeichert zu werden. Folglich wurden häufig mehr als 10 Festplattenvorgänge zum Abrufen von Dateien ausgeführt." Einzelbild. Nachdem die Verzeichnisgröße auf Hunderte von Bildern pro Verzeichnis reduziert wurde, würde das resultierende System im Allgemeinen immer noch drei Festplattenoperationen zum Abrufen eines Bildes ausführen: eine zum Lesen der Verzeichnismetadaten in den Speicher, eine zweite zum Laden des Inodes in den Speicher und eine dritte um den Inhalt der Datei zu lesen. "

Ich hatte angenommen, dass die Metadaten und der Inode des Dateisystemverzeichnisses vom Betriebssystem immer im RAM zwischengespeichert werden und für das Lesen einer Datei normalerweise nur 1 Festplatten-E / A erforderlich ist.

Ist dieses Problem "E / A mit mehreren Festplatten zum Lesen einer einzelnen Datei" in diesem Dokument nur für NAS-Appliances beschrieben, oder hat Linux auch das gleiche Problem?

Ich plane, einen Linux-Server zum Bereitstellen von Images auszuführen. Wie kann ich die Anzahl der Festplatten-E / A minimieren? Idealerweise sicherstellen, dass das Betriebssystem alle Verzeichnis- und Inode-Daten im RAM zwischenspeichert und für jede gelesene Datei nur nicht mehr als 1 Festplatten-E / A erforderlich ist.

user9517
quelle
1
Keine Antwort auf die Frage, aber Sie können immer Lack verwenden (Facebook verwendet ihn), der die Dateien im Speicher verwaltet. Auf diese Weise wird, wenn ein Image heiß wird (viele Anfragen an dieselbe Datei), die Festplatten-
Darhazer - Varnish würde hier nicht helfen, da der Linux-Datei-Cache (auf den sich Varnish stützt) bereits heiße Dateien im Speicher zwischenspeichert. Wenn Sie Varnish für die Bereitstellung statischer Dateien vor Nginx stellen, wird nichts hinzugefügt. Meine Frage ist, wann die Dateien zu groß / zu viele sind, um im Speicher zwischengespeichert zu werden. Ich möchte immer noch sicherstellen, dass mindestens die Verzeichnisdaten und Inodes zwischengespeichert werden, um die Festplatten-E / A auf nur 1 pro Lesevorgang zu reduzieren.
Viele Dateisysteme speichern den Inode im Verzeichnis, reduzieren die Anzahl der Anforderungen um eins und erhöhen die Wahrscheinlichkeit eines Cache-Treffers erheblich. Dies ist jedoch keine Programmierfrage.
Ben Voigt
Sie können die Blockgröße des Dateisystems beim Erstellen ändern, z. B. mit mke2fs -b 3276832 KB. Dies ist jedoch nur dann nützlich, wenn Sie keine kleinen Dateien in diesem Dateisystem haben.

Antworten:

5

Linux hat das gleiche "Problem". Hier ist ein Artikel, den ein Student von mir vor zwei Jahren veröffentlicht hat und in dem der Effekt unter Linux gezeigt wird. Die mehreren E / A können aus verschiedenen Quellen stammen:

  • Verzeichnissuche auf jeder Verzeichnisebene des Dateipfads. Möglicherweise müssen Sie den Verzeichnis-Inode und einen oder mehrere Verzeichniseintragsblöcke lesen
  • Inode der Datei

In normalen E / A-Mustern ist das Caching sehr effektiv und Inodes, Verzeichnisse und Datenblöcke werden so zugewiesen, dass Suchvorgänge reduziert werden. Die normale Suchmethode, die tatsächlich von allen Dateisystemen gemeinsam genutzt wird, ist jedoch für stark randomisierten Datenverkehr schlecht.

Hier einige Ideen:

1) Die Dateisystem-bezogenen Caches helfen. Ein großer Cache absorbiert die meisten Lesevorgänge. Wenn Sie jedoch mehrere Festplatten in einen Computer einlegen möchten, begrenzt das Verhältnis von Festplatte zu RAM, wie viel zwischengespeichert wird.

2) Verwenden Sie nicht Millionen kleiner Dateien. Aggregieren Sie sie zu größeren Dateien und speichern Sie den Dateinamen und den Versatz in der Datei.

3) Platzieren oder zwischenspeichern Sie die Metadaten auf einer SSD.

4) Und natürlich ein Dateisystem verwenden, das kein vollständig anarchisches Verzeichnisformat auf der Festplatte hat. Ein Readdir sollte nicht länger als die lineare Zeit dauern, und der direkte Dateizugriff sollte idealerweise nur die logarithmische Zeit sein.

Verzeichnisse klein zu halten (weniger als 1000 oder so) sollte nicht so viel helfen, da Sie mehr Verzeichnisse benötigen würden, in denen zwischengespeichert werden muss.

dmeister
quelle
Verwenden Sie natürlich ein Dateisystem, das kein vollständig archaisches Verzeichnisformat auf der Festplatte hat. Ein Readdir sollte nicht länger als die lineare Zeit dauern, und der direkte Dateizugriff sollte idealerweise nur die logarithmische Zeit sein.
Jørgensen
Ich fügte das der Antwort als 4. Punkt hinzu
dmeister
@dmeister Gutes Zeug. +1
Magellan
@dmeister Dein Link ist tot.
Don Scott
1

Dies hängt vom Dateisystem ab, das Sie verwenden möchten. Vor dem Lesen des Dateidatensystems:

  • Verzeichnisdatei lesen.
  • Lesen Sie den Inode Ihrer Datei
  • Lesen Sie Sektoren Ihrer Datei

Wenn der Ordner eine große Anzahl von Dateien enthält, ist dies ein großer Druck auf den Cache.


quelle
Wenn Sie die E / A-Zugriffe auflisten, ist es möglicherweise interessanter, diejenigen, die von ausgeführt werden, open()von denen zu trennen, die von ausgeführt werden read(). Die Seite win.tue.nl/~aeb/linux/vfs/trail.html zeigt einen schönen Überblick über die verschiedenen Kernel-Konzepte. (Vielleicht ist es veraltet Ich würde zu sagen , nicht in der Lage sein?)
ADL
0

Sie werden wahrscheinlich nicht in der Lage sein, alle Verzeichnis- und Inode-Daten im RAM zu behalten, da Sie wahrscheinlich mehr Verzeichnis- und Inode-Daten als RAM haben. Möglicherweise möchten Sie dies auch nicht, da dieser RAM möglicherweise besser für andere Zwecke verwendet wird. Würden Sie in Ihrem Bildbeispiel nicht lieber die Daten eines Bildes, auf das häufig zugegriffen wird, im RAM zwischengespeichert als den Verzeichniseintrag für ein Bild, auf das selten zugegriffen wird?

Trotzdem denke ich, dass der vfs_cache_pressure- Regler verwendet wird, um dies zu steuern. "Wenn vfs_cache_pressure = 0 ist, wird der Kernel aufgrund des Speicherdrucks niemals Dentries und Inodes zurückfordern, was leicht zu Speichermangel führen kann."

Samuel Edwin Ward
quelle