Speichern und Sichern von 10 Millionen Dateien unter Linux


25

Ich betreibe eine Website, auf der ungefähr 10 Millionen Dateien (Buchumschläge) in 3 Unterverzeichnissen gespeichert sind, im Bereich von [0-f]:

0/0/0/
0/0/1/
...
f/f/f/

Dies führt zu ungefähr 2400 Dateien pro Verzeichnis, was sehr schnell ist, wenn wir eine Datei abrufen müssen. Dies ist im Übrigen eine Praxis, die durch viele Fragen nahegelegt wird .

Wenn ich jedoch diese Dateien sichern muss, dauert es viele Tage, nur die 4k-Verzeichnisse mit 10m-Dateien zu durchsuchen.

Ich frage mich also, ob ich diese Dateien in einem Container (oder in 4k-Containern) speichern könnte, der sich jeweils genau wie ein Dateisystem verhält (eine Art gemounteter ext3 / 4-Container?). Ich denke, dies wäre fast so effizient wie der direkte Zugriff auf eine Datei im Dateisystem, und dies hätte den großen Vorteil, dass es sehr effizient auf einen anderen Server kopiert wird.

Irgendwelche Vorschläge, wie man das am besten macht? Oder irgendeine Alternative (noSQL, ...)?


Welches Dateisystem verwenden Sie gerade?
29.

NetApp ist nur eine Option, wenn Sie die Preise verbessern können
Ian Ringrose

Ich benutze ext4 unter CentOS 5.6
Benjamin

1
Neugierig, warum es "viele Tage dauern sollte, nur die 4k-Verzeichnisse mit 10m-Dateien zu durchsuchen", was viel zu langsam erscheint. Unter der Annahme von 150 Bytes pro Pfadname ergeben die 10-Millionen-Dateinamen 1,5 GB an Daten, sodass dies der verfügbare Speicher / die CPU sein kann (einschließlich des Sortierens des Ergebnisses). Überprüfen Sie auch, ob das Aktivieren / Deaktivieren von dir_index hilft: lonesysadmin.net/2007/08/17/… sowie verschiedene Tipps unter serverfault.com/questions/183821/…
RichVel,

Hinweis 5 Jahre später: Ich habe alles auf Amazon S3 migriert, das perfekt zum Speichern einer so großen Anzahl von Dateien geeignet ist. Außerdem muss ich keine Dateien mehr in 3 Ebenen von Unterverzeichnissen aufteilen, da dies für S3 keinen Unterschied macht (ein Pfad ist ein Pfad, ob er Schrägstriche enthält oder nicht, macht keinen Unterschied). Und ich kann besser schlafen, da ich weiß, dass meine Daten an mehreren Standorten sicher repliziert werden.
Benjamin

Antworten:


11

Optionen für den schnellen Zugriff auf und die Sicherung von Millionen von Dateien

Leihen Sie sich von Leuten mit ähnlichen Problemen

Dies hört sich nach einem einfacheren Problem an, mit dem USENET-Newsserver und das Zwischenspeichern von Web-Proxys konfrontiert sind: Hunderte Millionen kleiner Dateien, auf die zufällig zugegriffen wird. Möglicherweise möchten Sie ihnen einen Hinweis geben (es sei denn, sie müssen in der Regel keine Sicherungen durchführen).

http://devel.squid-cache.org/coss/coss-notes.txt

http://citeseer.ist.psu.edu/viewdoc/download;jsessionid=4074B50D266E72C69D6D35FEDCBBA83D?doi=10.1.1.31.4000&rep=rep1&type=pdf

Offensichtlich ist die zyklische Natur des zyklischen Nachrichtendateisystems für Sie irrelevant, aber das Konzept auf niedrigerer Ebene, mehrere Festplattendateien / -geräte mit gepackten Bildern und einem schnellen Index aus den Informationen zu haben, die der Benutzer zum Nachschlagen der Standortinformationen bereitstellt, ist sehr angemessen.

Dedizierte Dateisysteme

Natürlich handelt es sich hierbei nur um ähnliche Konzepte wie bei der Erstellung eines Dateisystems in einer Datei und dem Mounten über Loopback, mit der Ausnahme, dass Sie Ihren eigenen Dateisystemcode schreiben müssen. Natürlich können Sie, da Sie sagten, Ihr System sei meistens lesbar, eine Festplattenpartition (oder eine Lvm-Partition für flexible Größenanpassung) für diesen einen Zweck verwenden. Wenn Sie eine Sicherungskopie erstellen möchten, hängen Sie das Dateisystem schreibgeschützt ein und erstellen Sie eine Kopie der Partitionsbits.

LVM

Ich habe LVM oben als nützlich bezeichnet, um die dynamische Größe einer Partition zu ermöglichen, sodass Sie nicht viel leeren Speicherplatz sichern müssen. Natürlich bietet LVM auch andere Funktionen, die möglicherweise sehr nützlich sind. Insbesondere die "Snapshot" -Funktion, mit der Sie ein Dateisystem zu einem bestimmten Zeitpunkt einfrieren können. Jeder Unfall rm -rfoder was auch immer würde den Schnappschuss nicht stören. Je nachdem, was Sie genau tun möchten, kann dies für Ihre Backups ausreichend sein.

RAID-1

Ich bin mir sicher, dass Sie mit RAID bereits vertraut sind und es wahrscheinlich bereits aus Gründen der Zuverlässigkeit verwenden, aber RAID-1 kann auch für Sicherungen verwendet werden, zumindest wenn Sie Software-RAID verwenden (Sie können es mit Hardware-RAID verwenden, aber tatsächlich Dies führt zu einer geringeren Zuverlässigkeit, da möglicherweise dasselbe Modell bzw. derselbe Revisionscontroller zum Lesen erforderlich ist. Das Konzept besteht darin, dass Sie eine RAID-1-Gruppe mit einer weiteren Festplatte erstellen, als für Ihre normalen Zuverlässigkeitsanforderungen tatsächlich erforderlich ist (z. B. eine dritte Festplatte, wenn Sie Software-RAID-1 mit zwei Festplatten verwenden, oder eine große Festplatte und eine Hardware- RAID5 mit kleineren Festplatten mit einem Software-RAID-1 über dem Hardware-RAID-5. Wenn eine Sicherungskopie erstellt werden soll, installieren Sie eine Festplatte, bitten Sie mdadm, diese Festplatte der RAID-Gruppe hinzuzufügen, warten Sie, bis die Vollständigkeit angezeigt wird, und fordern Sie optional ein Überprüfungs-Scrub an. Entfernen Sie dann die Festplatte. Na sicher,


Sehr vollständige Antwort, die gute Lösungen zusammenfasst. Ich denke, ich werde meine vorhandene Dateisystemstruktur beibehalten und LVM-Snapshots verwenden, was für meinen Anwendungsfall perfekt zu sein scheint.
Benjamin

9

Sie können ein virtuelles Dateisystem mit dem Loopback-Manager bereitstellen. Dies würde zwar den Sicherungsvorgang beschleunigen, könnte jedoch den normalen Betrieb beeinträchtigen.

Eine andere Alternative besteht darin, das gesamte Gerät mit dd zu sichern. Zum Beispiel dd if=/dev/my_device of=/path/to/backup.dd.


+1 Ein Backup des Geräts selbst ist eine gute Idee.
asm

3
Wenn Sie diesen Ansatz verwenden, sollten Sie die Wiederherstellung testen (nun, das sollten Sie immer tun), denn wenn Ihre Eingabe eine Festplatte wie / dev / sdd ist, speichert dd das Partitionsschema und die Partitionsgrößen. Wenn Sie es auf einem kleineren Datenträger wiederherstellen, werden Fehler angezeigt, und wenn Sie es auf einem größeren Datenträger wiederherstellen, wird es abgeschnitten angezeigt. Es funktioniert am besten, wenn Sie die Daten auf einem anderen Exemplar desselben Festplattentyps wiederherstellen. Das Wiederherstellen nur von Partitionen (/ dev / sdd1) ist weniger problematisch.
Benutzer unbekannt

1
Beachten Sie, dass, wenn sich das Gerät in LVM befindet, eine Sicherung auch durchgeführt werden kann, ohne die Bereitstellung der Festplatte mithilfe von LVM-Snapshots aufzuheben.
bdonlan

Ich unterstütze den LVM-Snapshot-Backup-Ansatz. Ich habe in der Vergangenheit lvm für die Live-DR-Replikation genutzt. Durch die Verwendung von dd in Kombination mit Snapshots ist es einfach, schnelle Backups auf Blockebene durchzuführen.
Slashdot

Ich habe versucht , ddüber ncund dies macht einen guten Job! Möglicherweise habe ich jedoch inkonsistente / beschädigte Daten, anstatt LVM-Snapshots anstelle der Live-Partition zu verwenden.
Benjamin

8

Wie Sie wahrscheinlich wissen, liegt Ihr Problem in der Lokalität. Eine typische Festplattensuche dauert ungefähr 10 ms. Das Aufrufen von "stat" (oder open ()) für 10 Millionen zufällig platzierte Dateien erfordert 10 Millionen Suchvorgänge oder ungefähr 100000 Sekunden oder 30 Stunden.

Sie müssen Ihre Dateien also in größeren Containern ablegen, sodass die relevante Zahl Ihre Laufwerksbandbreite (normalerweise 50-100 MB / s für eine einzelne Festplatte) und nicht Ihre Suchzeit ist. Sie können auch ein RAID darauf werfen, mit dem Sie die Bandbreite erhöhen (aber die Suchzeit nicht verringern).

Ich sage Ihnen wahrscheinlich nichts, was Sie noch nicht wissen, aber mein Punkt ist, dass Ihre "Container" -Idee das Problem definitiv lösen wird und so gut wie jeder Container. Loopback-Halterungen funktionieren wahrscheinlich genauso gut wie alles andere.


Ja, die Lokalität ist entscheidend. Sehen Sie sich Ihre Nutzungsmuster an. Die meisten Probleme richten sich nach dem Pareto-Prinzip (80% der Prozesse treffen auf 20% der Daten). Wenn Sie also herausfinden möchten, welche Dateien im RAM zwischengespeichert werden müssen, oder einfach eine separate Partition mit einem anderen Verzeichnislayout erstellen möchten, müssen Sie dies tun Es dauert weniger Verzeichnissuchen oder -suchen, es würde wahrscheinlich viel helfen. Das Verteilen der Dateien, auf die häufig zugegriffen wird, auf verschiedene Datenträgerspindeln, sodass Suchvorgänge parallel ausgeführt werden können, kann ebenfalls hilfreich sein. +1 für @nemo zum Aufrufen des Referenzorts.
Marcin

5

Es gibt mehrere Möglichkeiten. Die einfachste Methode, die mit allen Linux-Dateisystemen funktionieren sollte, besteht darin, dddie gesamte Partition ( /dev/sdb3oder /dev/mapper/Data-ImageVol) in ein einzelnes Image zu kopieren und dieses Image zu archivieren. Wenn Sie einzelne Dateien wiederherstellen möchten, hängen Sie das Image ( mount -o loop /usr/path/to/file /mountpoint) per Loopback ein und kopieren Sie die benötigten Dateien heraus. Für eine vollständige Partitionswiederherstellung können Sie die Richtung des ursprünglichen ddBefehls umkehren , benötigen jedoch eine Partition mit identischer Größe.

Nach Ihrem Anwendungsfall zu urteilen, sind einzelne Datei-Wiederherstellungen ein sehr seltenes Ereignis, wenn überhaupt. Aus diesem Grund ist ein Image-basiertes Backup hier wirklich sinnvoll. Wenn Sie einzelne Wiederherstellungen häufiger durchführen müssen, ist die Verwendung von gestaffelten LVM-Snapshots wesentlich praktischer. Sie müssen jedoch immer noch die Image-basierte Sicherung für die kritischen Katastrophen durchführen, bei denen "wir haben alles verloren". Image-basierte Wiederherstellungen sind in der Regel viel schneller als tar-basierte Wiederherstellungen, da sie nur Blöcke wiederherstellen, nicht bei jedem Öffnen / Schließen eine ganze Reihe von Metadatenoperationen ausführen und auch eine sehr sequentielle Festplattenoperation für sein können weitere Geschwindigkeit steigt.

Wie das Google-Video @casey bereits zur Hälfte erwähnt hat, ist XFS ein großartiges Dateisystem (wenn auch komplex). Eines der besseren Hilfsprogramme mit XFS ist das xfsdumpHilfsprogramm, mit dem ein gesamtes Dateisystem in eine einzelne Datei kopiert wird, und das im Allgemeinen schneller als tarmöglich. Es ist ein dateisystemspezifisches Dienstprogramm, das die Vorteile von fs-Interna auf eine Weise nutzen kann, die tar nicht kann.


Viele gute Antworten da! XFS scheint interessant zu sein, aber ich fürchte, es ist ein bisschen außerhalb meiner Reichweite.
Benjamin


2

Vielleicht eine vereinfachte Antwort, aber mein erster Gedanke war, so etwas wie GridFS zu verwenden , das auf MongoDB aufbaut . Viele der primären Sprachtreiber unterstützen es sofort, daher sollten Sie es einfach mit den Abschnitten zum Lesen von Dateien in Ihrem Code austauschen können. Sie können auch einfach Ihre vorhandenen Verzeichnispfade als Schlüssel für diese Dateien festlegen.

Ein Problem, das Sie haben könnten, ist, dass Mongo dazu neigt, ziemlich schnell langsamer zu werden, wenn es die ganze Zeit von der Festplatte sucht. Ich gehe davon aus, dass sich mit 10 Millionen Dateien die meisten Ihrer Daten auf der Festplatte befinden werden. Wie ich mich erinnere, sind die Datenblöcke in GridFS 4 MB groß. Wenn Ihre Dateien also größer sind, müssen Sie mehrere kostspielige Vorgänge ausführen, um eine Datei zu erhalten. Ich denke, der Schlüssel wäre, Ihre Dateien basierend auf Ihrer bereits aufgeräumten Verzeichnisstruktur zu speichern, damit Sie mehrere Instanzen von Mongo auf mehreren Boxen ausführen können, um die Last zu verringern. Ich weiß jedoch auch nicht, wie hoch Ihre Leistungsanforderungen sind, daher überlege ich es mir vielleicht.

Was ist der Vorteil von all dem? Leistung, die den Festplattenlesevorgängen ziemlich nahe kommt, wenn sie richtig ausgeführt wird. Darüber hinaus bietet Mongo mehrere großartige integrierte Möglichkeiten, um die gesamte Datenmenge in einer DB-Instanz schnell zu sichern , auch wenn die Datenbank noch ausgeführt wird.


Werde auf jeden Fall einen Blick auf GridFS werfen, den ich nicht kannte, aber ich denke, dass ich am Ende alles dateisystembasiert behalten werde, um den Arbeitsaufwand zu verringern, da bereits alles funktioniert!
Benjamin

1

Wenn Sie mit einem Appliance-Modell für Ihre Datenspeicherung zufrieden sind , können Sie NexentaStor in Betracht ziehen . Es führt ZFS unter OpenSolaris unter der Haube aus, aber die gesamte Verwaltung erfolgt über eine Web-GUI.

Es gibt einige Funktionen, die bei Ihrem Problem helfen können.

  • Die Enterprise-Version unterstützt eine Form der Remote-Replikation auf der Basis von Snapshots, bei der nicht das gesamte Dateisystem gescannt werden muss.

  • Wenn es Ihnen nichts ausmacht, sich die Hände schmutzig zu machen, bietet ZFS einen sehr praktischen ZFS-Diff- Befehl, mit dem Sie effizient feststellen können, welche Dateien seit dem letzten Schnappschuss hinzugefügt, geändert oder gelöscht wurden, ohne das gesamte Dateisystem durchsuchen zu müssen. Sie können dies in Ihr Backup-System integrieren, um die für inkrementelle Backups erforderliche Zeit erheblich zu verkürzen.


Danke, schau es dir an. Vielleicht würde es meinem Projekt jedoch ein wenig Komplexität verleihen!
Benjamin

1

Sie können ein Standarddienstprogramm dumpzum Sichern des EXT4-Dateisystems mit vielen Dateien verwenden. Dieses Dienstprogramm überprüft zunächst, welche Blöcke in einem Dateisystem verwendet werden, und sichert sie dann in der Reihenfolge der Datenträger, wodurch die meisten Suchvorgänge beseitigt werden.

Es gibt ein entsprechendes restoreDienstprogramm zum Wiederherstellen von Backups, die von erstellt wurden dump.

Es unterstützt inkrementelle Sicherungen mit Sicherungsstufen 1, die gegenüber der letzten Sicherungsstufe 0 (vollständige Sicherung) geändert wurden, und mit Sicherungsstufen 2, die gegenüber Sicherungsstufe 1 geändert wurden, und so weiter.


0

Bei inkrementellen Sicherungen besteht eine Option darin, einen zweiten Schattenbaum für neue Cover zu erstellen. Das heißt, Sie hätten Ihren Hauptbaum, der für alle Leseoperationen verwendet wird. Sie hätten auch ein newfiles/012345.....jpgVerzeichnis; Neu hinzugefügte Cover erstellen hier und im Hauptbaum einen Hardlink. Bei der Durchführung von Sicherungen können Sie den Hauptbaum gelegentlich sichern, den (viel kleineren) newfilesBaum jedoch viel häufiger.

Beachten Sie, dass Sie den newfilesBaum für neue Dateien leeren können , um ihn klein zu halten , bevor Sie eine neue Sicherung des Hauptbaums durchführen:

mv newfiles newfiles_
mkdir newfiles
rm -rf newfiles_

Sobald Sie dies tun, sind Sie natürlich verpflichtet, eine neue Sicherung des Hauptbaums zu erstellen.


Interessanter Ansatz, danke fürs Teilen. Ich befürchte jedoch, dass dies viele Änderungen in der Anwendung mit sich bringen würde und es schwierig sein würde, die Anwendung und die Speicheranforderungen in zwei separaten Ebenen zu halten.
Benjamin

0

Das Hinzufügen von ein wenig Parallelität hilft normalerweise.

Ich habe ein ähnliches Problem wie Sie. In meinem Fall muss ich ungefähr 30 Millionen Dateien sichern, die meisten davon HTML-, PHP- oder JPEG-Dateien. Für mich funktioniert BackupPC + rsync über ssh irgendwie in Ordnung; Die vollständige Sicherung dauert ungefähr einen Tag, aber inkrementelle Sicherungen werden in der Regel in wenigen Stunden abgeschlossen sein.

Der Trick besteht darin, jedes Hauptverzeichnis (0, 1, 2 ... a, b, c ...) als neues Ziel hinzuzufügen, das in BackupPC kopiert werden soll, und die Sicherung parallel ausführen zu lassen, sodass Verzeichnisse gleichzeitig gesichert werden a / , b / , c / * und so weiter. Abhängig von Ihrem Festplattensubsystem ist eine Anzahl von Prozessen bis zu 10 Prozessen wahrscheinlich die schnellste Methode zum Sichern.

LVM-Snapshots und Backups auf Blockebene sind ebenfalls eine Option. Mit Backups auf BackuPC- und Dateiebene können Sie jedoch bei Bedarf einzelne Dateien oder Verzeichnisse wiederherstellen.


Ich bin überrascht, dass das gleichzeitige Sichern der Stammverzeichnisse das Problem für Sie löst. Ich würde davon ausgehen, dass es tatsächlich langsamer ist. Befinden sich alle Verzeichnisse auf derselben Festplatte? Verwenden Sie eine SSD?
Benjamin

Die Datendateien werden im SAN gespeichert.
Janne Pikkarainen

Okay, jetzt macht es Sinn, dass Sie effizienter auf mehrere Dateien gleichzeitig zugreifen, da sich Ihre verschiedenen Ordner höchstwahrscheinlich physisch auf verschiedenen Laufwerken im SAN befinden oder zumindest auf mehreren Laufwerken repliziert werden, was den gleichzeitigen Zugriff ermöglicht. Da ich nur auf einem RAID-1-System arbeite, ist es sehr wahrscheinlich, dass meine Geschwindigkeit bei mehr als zwei gleichzeitigen Zugriffen abnimmt.
Benjamin

0

Benjamin,

Ich denke, dass Ihr Problem an der Anzahl der Dateien pro Verzeichnisebene behoben werden kann!

Ändert sich die Zugriffszeit erheblich, wenn Sie 20 000 Dateien in einem Verzeichnis speichern?

Haben Sie beim Speichern der Dateisystem-Metadaten auf einem separaten Laufwerk mit schnellerem Zugriff (z. B. einer SSD) auch darüber nachgedacht?


0

Ich würde stattdessen eine gute alte relationale Datenbank empfehlen.

Ich würde ein PostgreSQL mit beispielsweise 256 partitionierten Tabellen (cover_00, cover_01, ..., cover_ff) mit Bilddaten als bytea(binäre) Spalte mit externem Speicher und einer Dateikennung als Primärschlüssel verwenden. Das Abrufen eines Images wäre schnell (dank eines Indexes für den Primärschlüssel), die Datenintegrität wäre gewährleistet (ACID-konforme Datenbank), das Backup wäre in Festplattenreihenfolge, sodass nicht zu viel gesucht wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.