Frage Speichern einer Million Bilder im Dateisystem


Ich habe ein Projekt, das eine große Anzahl von Bildern erzeugen wird. Rund 1.000.000 für den Start. Sie sind keine großen Bilder, also werde ich sie alle auf einer Maschine am Anfang speichern.

Wie empfehlen Sie, diese Bilder effizient zu speichern? (NTFS-Dateisystem derzeit)

Ich überlege mir ein Benennungsschema ... zum Start haben alle Bilder einen inkrementellen Namen von 1 bis Ich hoffe, das hilft mir später bei Bedarf zu sortieren und in verschiedene Ordner zu werfen.

Was wäre ein besseres Namensschema?

a / b / c / 0 ... z / z / z / 999

oder

a / b / c / 000 ... z / z / z / 999

Irgendeine Idee dazu?


75
2017-12-17 16:52


Ursprung


Sind sie an bestimmte Benutzer gebunden oder nur generisch? Sind sie in irgendeiner Weise gruppiert?
nur generisch. eine Reihe von Bildern, die von irgendeiner technischen Ausrüstung erzeugt werden. Ich nenne sie inkrementell von 1 nach oben, um die Idee eines Zeitbezuges zu haben. - s.mihai
Wie werden sie benutzt / zugegriffen? durch eine maßgeschneiderte App oder was? - dove
Bist du das? i46.tinypic.com/1z55k7q.jpg
:)) Ja ... 1 Mil. Porno Bilder :)) - s.mihai


Antworten:


Ich würde empfehlen, ein normales Dateisystem anstelle von Datenbanken zu verwenden. Die Verwendung eines Dateisystems ist einfacher als eine Datenbank, Sie können normale Tools verwenden, um auf Dateien zuzugreifen, Dateisysteme sind für diese Art der Nutzung usw. ausgelegt. NTFS sollte als Speichersystem gut funktionieren.

Speichern Sie nicht den tatsächlichen Pfad zur Datenbank. Es ist besser, die Sequenznummer des Bildes in der Datenbank zu speichern und Funktionen zu haben, die den Pfad von der Sequenznummer erzeugen können. z.B:

 File path = generatePathFromSequenceNumber(sequenceNumber);

Es ist einfacher zu handhaben, wenn Sie die Verzeichnisstruktur ändern müssen. Vielleicht müssen Sie die Bilder an einen anderen Ort verschieben, vielleicht haben Sie keinen Platz mehr und Sie fangen an, einige der Bilder auf der Festplatte A und einige auf der Festplatte B usw. zu speichern. Es ist einfacher, eine Funktion zu ändern als Pfade in der Datenbank zu ändern .

Ich würde diese Art von Algorithmus zum Generieren der Verzeichnisstruktur verwenden:

  1. Platzieren Sie zuerst die Folgenummer mit führenden Nullen, bis Sie mindestens eine 12-stellige Zeichenfolge haben. Dies ist der Name für Ihre Datei. Vielleicht möchten Sie ein Suffix hinzufügen:
    • 12345 -> 000000012345.jpg
  2. Teilen Sie die Zeichenfolge dann in zwei oder drei Zeichenblöcke auf, wobei jeder Block eine Verzeichnisebene angibt. Haben Sie eine feste Anzahl von Verzeichnisebenen (zB 3):
    • 000000012345 -> 000/000/012
  3. Speichern Sie die Datei im untergenerierten Verzeichnis:
    • Daher der vollständige Pfad und Dateiname für die Datei mit der Sequenz-ID 123 ist 000/000/012/00000000012345.jpg
    • Für Datei mit Sequenz-ID 12345678901234 der Weg wäre 123/456/789/12345678901234.jpg

Einige Dinge, die Sie bei Verzeichnisstrukturen und beim Dateispeicher beachten sollten:

  • Obiger Algorithmus gibt Ihnen ein System, in dem jedes Blattverzeichnis maximal 1000 Dateien enthält (wenn Sie insgesamt weniger als 1 000 000 000 000 Dateien haben)
  • Es kann Grenzen geben, wie viele Dateien und Unterverzeichnisse ein Verzeichnis beispielsweise enthalten kann ext3-Dateisystem unter Linux hat ein Limit von 31998 Unterverzeichnissen pro Verzeichnis.
  • Normale Werkzeuge (WinZip, Windows Explorer, Befehlszeile, Bash Shell, etc.) funktionieren möglicherweise nicht sehr gut, wenn Sie eine große Anzahl von Dateien pro Verzeichnis (> 1000) haben
  • Die Verzeichnisstruktur selbst benötigt etwas Speicherplatz, so dass Sie nicht zu viele Verzeichnisse benötigen.
  • Mit der obigen Struktur können Sie immer den richtigen Pfad für die Bilddatei finden, indem Sie einfach auf den Dateinamen schauen, wenn Sie Ihre Verzeichnisstrukturen durcheinander bringen.
  • Wenn Sie auf Dateien von mehreren Computern aus zugreifen müssen, sollten Sie die Dateien über ein Netzwerkdateisystem freigeben.
  • Die obige Verzeichnisstruktur funktioniert nicht, wenn Sie viele Dateien löschen. Es hinterlässt "Löcher" in der Verzeichnisstruktur. Aber da Sie keine Dateien löschen, sollte es in Ordnung sein.

70
2017-12-17 17:32



sehr interessant! Den Dateinamen aufteilen ... daran habe ich nicht gedacht. Ich nehme an, das ist die elegante Art, es zu tun: -? - s.mihai
Ein Hash (z. B. MD5) als Name der Datei sowie die Verzeichnisverteilung würden funktionieren. Die Integrität der Dateien wäre nicht nur ein Nebeneffekt des Benennungsschemas (leicht zu überprüfen), sondern Sie haben eine ziemlich gleichmäßige Verteilung in der gesamten Verzeichnishierarchie. Wenn Sie also eine Datei namens "f6a5b1236dbba1647257cc4646308326.jpg" haben, würden Sie sie in "/ f / 6" speichern (oder so tief wie Sie möchten). 2 tiefe Ebenen ergeben 256 Verzeichnisse oder knapp 4000 Dateien pro Verzeichnis für die ersten 1-m-Dateien. Es wäre auch sehr einfach, die Umverteilung auf ein tieferes Schema zu automatisieren.
+1 Ich habe gerade bemerkt, dass diese Antwort ähnlich der war, die ich gerade gepostet habe. - 3dinfluence
Ich stimme definitiv zu, das Dateisystem zu verwenden und einen künstlichen Bezeichner zu erstellen, der sich in Ordnernamen aufteilt. Sie sollten jedoch auch versuchen, eine zufällige Verteilung von Identifikatoren zu erhalten, d. H. Verwenden Sie keine Sequenznummer. Das würde Ihnen erlauben, einen ausgewogeneren Baum von Ordnern zu haben. Bei einer zufälligen Verteilung können Sie den Baum außerdem einfacher auf mehrere Dateisysteme verteilen. Ich würde auch ein ZFS-basiertes SAN mit aktiviertem Dedup und einem sparsamen Volume für jedes Dateisystem verwenden. Sie können trotzdem NTFS verwenden, indem Sie iSCSI für den Zugriff auf das SAN verwenden. - Michael Dillon
Wenn Sie in Schritt 2 von rechts nach links gehen, werden die Dateien gleichmäßig verteilt. Außerdem müssen Sie sich keine Sorgen machen, dass Sie nicht genug Nullen füllen, da Sie eine unbegrenzte Anzahl von Dateien haben können - ropo


Ich werde meine 2 Cent auf einen negativen Ratschlag setzen: Gehen Sie nicht mit einer Datenbank.

Ich arbeite seit Jahren mit Datenbanken, die Bilder speichern: große (1 Meg -> 1 Gig) Dateien, oft geändert, mehrere Versionen der Datei, die relativ oft aufgerufen werden. Die Datenbankprobleme, in die Sie geraten, wenn große Dateien gespeichert werden, sind extrem langwierig zu handhaben, Schreib- und Transaktionsprobleme sind knorrig, und Sie stoßen auf Locking-Probleme, die große Probleme verursachen können Wracks. Ich habe mehr Übung beim Schreiben von dbcc-Skripten und beim Wiederherstellen von Tabellen aus Sicherungskopien als jede normale Person je haben.

Die meisten der neueren Systeme, mit denen ich gearbeitet habe, haben den Dateispeicher in das Dateisystem verschoben und verlassen sich auf Datenbanken für nichts anderes als Indexierung. Dateisysteme sind darauf ausgelegt, diese Art von Missbrauch zuzulassen, sie sind viel einfacher zu erweitern und Sie verlieren selten das gesamte Dateisystem, wenn ein Eintrag beschädigt wird.


29
2017-12-17 17:12



Ja. Notiz genommen! - s.mihai
Haben Sie sich den FILESTREAM-Datentyp von SQL 2008 angesehen? Es ist eine Kreuzung zwischen Datenbank- und Dateisystemspeicher. - NotMe
+1, wenn Sie lieber mit dem Dateiserver als mit einer Datenbank arbeiten, da Sie schnelle und seltene IO-Operationen durchführen.
Was ist, wenn Sie nur ein paar hundert Dokumente oder Bilder pro Datenbank speichern - ein Nachteil der Datenbank für die Speicherung? - Beep beep
+1 ... ein Dateisystem ist sowieso irgendwie eine "Datenbank" (ntfs sicher), also warum es zu kompliziert machen. - akira


Ich denke, dass die meisten Websites, die damit zu tun haben, einen Hash der Art verwenden, um sicherzustellen, dass die Dateien gleichmäßig in den Ordnern verteilt werden.

Also sagen Sie, Sie haben einen Hash einer Datei, die ungefähr so ​​ist 515d7eab9c29349e0cde90381ee8f810
Sie können dies am folgenden Speicherort gespeichert haben und Sie können wie viele Ebenen tief verwenden, um die Anzahl der Dateien in jedem Ordner niedrig zu halten.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

Ich habe diesen Ansatz viele Male gesehen. Sie benötigen weiterhin eine Datenbank, um diese Dateihashes einem lesbaren Namen und allen anderen Metadaten zuzuordnen, die Sie speichern müssen. Aber dieser Ansatz skaliert ziemlich gut b / c Sie können beginnen, den Hash-Adressraum zwischen mehreren Computern und oder Speicherpools usw. zu verteilen.


12
2017-12-17 20:17



Git verwendet einen ähnlichen Ansatz: git-scm.com/book/de/v2/Git-Internals-Git-Objects (um diese Antwort zu unterstützen) - aexl


Im Idealfall sollten Sie für verschiedene Strukturen Tests auf zufällige Zugriffszeiten durchführen, da Ihre spezifische Festplattenkonfiguration, Caching, verfügbarer Speicher usw. diese Ergebnisse ändern können.

Angenommen, Sie haben die Kontrolle über die Dateinamen, würde ich sie auf der Ebene von 1000s pro Verzeichnis partitionieren. Je mehr Verzeichnisebenen Sie hinzufügen, desto mehr Inodes verbrennen Sie, also gibt es hier einen Push-Pull.

Z.B.,

/ root / [0-99] / [0-99] / Dateiname

Hinweis, http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx hat mehr Details zum NTFS-Setup. Insbesondere "Wenn Sie eine große Anzahl von Dateien in einem NTFS-Ordner verwenden (300.000 oder mehr), deaktivieren Sie die Generierung kurzer Dateinamen, um eine bessere Leistung zu erzielen, insbesondere, wenn die ersten sechs Zeichen der langen Dateinamen ähnlich sind."

Sie sollten auch in das Deaktivieren von Dateisystemfunktionen schauen, die Sie nicht benötigen (z. B. die letzte Zugriffszeit). http://www.pctools.com/guides/registry/detail/50/


11
2017-12-17 17:01



+1 zum Deaktivieren der 8.3-Dateinamenerstellung und der letzten Zugriffszeit; Das war das Erste, was mir in den Sinn kam, als ich "riesige Anzahl von [Dateien]" und "NTFS" (Windows) las. - rob
verlinken ........................ - Pacerier


Was auch immer Sie tun, speichern Sie sie nicht alle in einem Verzeichnis.

Abhängig von der Verteilung der Namen dieser Bilder können Sie eine Verzeichnisstruktur erstellen, in der Sie Ordner auf der obersten Ebene mit einem einzigen Buchstaben haben, in denen Sie weitere Unterordner für den zweiten Bildbuchstaben usw. haben.

So:

Mappe img\a\b\c\d\e\f\g\ würde die Bilder enthalten, die mit 'abcdefg' beginnen und so weiter.

Sie können Ihre eigene erforderliche erforderliche Tiefe einführen.

Das Tolle an dieser Lösung ist, dass die Verzeichnisstruktur effektiv wie ein Hashtable / Dictionary funktioniert. Wenn Sie einen Bilddateinamen angegeben haben, kennen Sie sein Verzeichnis und geben ein Verzeichnis an. Sie werden eine Teilmenge der Bilder kennen, die dorthin gehen.


7
2017-12-17 16:58



\ a \ b \ c \ d \ e \ f \ Ich mache jetzt, ich dachte, es gibt einen weisen Weg, dies zu tun. - s.mihai
Das ist eine allgemein akzeptierte Lösung, wie man sie physisch speichert. Die Generierung der Bild-URLs kann leicht dynamisch anhand des Bilddateinamens erfolgen. Um sie zu bedienen, könnten Sie sogar img-a, img-b Subdomains auf dem Bilderserver einführen, um Ladezeiten zu verkürzen.
Und +1 für "nicht alle in einem Verzeichnis speichern". Ich unterstütze ein Legacy-System, das 47000 Dateien auf einem Server in einem einzigen Ordner abgelegt hat, und es dauert etwa eine Minute, bis der Explorer den Ordner öffnet. - Mark Ransom
Durch das Ausführen eines \ b \ c \ d \ e \ f \ g wird die Verzeichnisstruktur sehr tief und jedes Verzeichnis enthält nur wenige Dateien. Besser, mehr als einen Brief pro Verzeichnisebene zu verwenden, z. ab \ cd \ ef \ oder abc \ def \. Verzeichnisse belegen auch Speicherplatz von Festplatte, so dass Sie nicht zu viele von ihnen möchten. - Juha Syrjälä
Ich musste eine Anwendung mit 4 + Millionen Dateien in einem Verzeichnis unterstützen. Es funktionierte überraschend gut, aber Sie konnten NIEMALS Forscher zum Öffnen des Ordners bekommen, es würde ständig die neuen Zusätze sortieren. +1 für NTFS, um es ohne zu sterben zu handhaben. - SqlACID


Ich würde diese auf dem Dateisystem speichern, aber es hängt davon ab, wie schnell die Anzahl der Dateien wächst. Werden diese Dateien im Internet gehostet? Wie viele Benutzer würden auf diese Datei zugreifen? Dies sind die Fragen, die beantwortet werden müssen, bevor ich Ihnen eine bessere Empfehlung geben kann. Ich würde auch Haystack von Facebook sehen, sie haben eine sehr gute Lösung zum Speichern und Servieren von Bildern.

Auch wenn Sie Dateisystem wählen, müssen Sie diese Dateien mit Verzeichnissen partitionieren. Ich habe mir dieses Thema angeschaut und eine Lösung vorgeschlagen, die aber keineswegs perfekt ist. Ich partitioniere durch Hashtabelle und Benutzer können Sie mehr auf meinem lesen Blog.


5
2017-12-17 16:59



Die Bilder sind nicht für den häufigen Zugriff gedacht. Es gibt also kein Problem damit. ihre Zahl wird ziemlich schnell wachsen. Ich nehme an, dass es die 1mil geben wird. Marke in 1 Monat. - s.mihai
Ich interessiere mich für die Programmierer-Ansicht, damit ich das nicht zu sehr überdenke - s.mihai
Wenn Sie also keinen schnellen Zugriff benötigen, ist Haystack wahrscheinlich nicht für Sie geeignet. Die Verwendung von Verzeichnissen für Partitionen ist aus meiner Sicht die einfachste Lösung. - Lukasz


Wir haben ein Foto-Shop-System mit 4 Millionen Bildern. Wir verwenden die Datenbank nur für Metadaten und alle Bilder werden im Dateisystem unter Verwendung eines inversen Namensgebungssystems gespeichert, wobei Ordnernamen aus der letzten Stelle der Datei, last-1 usw. erzeugt werden. z.B.: 000001234.jpg wird in der Verzeichnisstruktur wie 4 \ 3 \ 2 \ 1 \ 000001234.jpg gespeichert.

Dieses Schema funktioniert sehr gut mit dem Identitätsindex in der Datenbank, da es die gesamte Verzeichnisstruktur gleichmäßig ausfüllt.


5
2017-12-30 22:10





Quick-Point, Sie müssen keinen Dateipfad in Ihrer Datenbank speichern. Sie können nur einen numerischen Wert speichern, wenn Ihre Dateien in der von Ihnen beschriebenen Weise benannt sind. Wenn Sie dann eines der bereits beschriebenen, wohldefinierten Speicherschemata verwenden, können Sie den Index als Zahl abrufen und die Datei sehr schnell finden, indem Sie die Verzeichnisstruktur durchlaufen.


4
2017-12-17 17:18



: -? guter schneller Punkt. Nur, dass ich jetzt keinen Algorithmus zum Generieren des Pfades habe. - s.mihai


Das neue MS SQL 2008 hat eine neue Funktion für solche Fälle, es heißt FILESTREAM. Schau mal:

Microsoft TechNet FILESTREAM Übersicht


4
2017-12-17 17:24