Speichern einer Million Bilder im Dateisystem

79

Ich habe ein Projekt, das eine große Anzahl von Bildern erzeugen wird. Rund 1.000.000 für den Start. Da es sich nicht um große Bilder handelt, speichere ich sie beim Start auf einem Computer.

Wie empfehlen Sie die effiziente Speicherung dieser Bilder? (NTFS-Dateisystem derzeit)

Ich überlege mir ein Benennungsschema ... zum Start haben alle Bilder einen inkrementellen Namen von 1 bis Ich hoffe, dies hilft mir, sie später zu sortieren, wenn nötig, und sie in verschiedene Ordner zu werfen.

Was wäre ein besseres Benennungsschema:

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

oder

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

Irgendeine Idee dazu?

am mihai
quelle
1
Sind sie an bestimmte Benutzer gebunden oder nur generisch? Sind sie in irgendeiner Weise gruppiert?
nur generisch. eine Reihe von Bildern, die von einigen technischen Geräten erzeugt wurden. Ich benenne sie inkrementell von 1 bis nur um eine Vorstellung von einer Zeitreferenz zu haben.
Am Mittwoch, den
Wie werden sie genutzt / genutzt? über eine maßgeschneiderte App oder was?
Taube
16
Bist du das? i46.tinypic.com/1z55k7q.jpg
1
:)) ja ... 1 mil.
porno

Antworten:

73

Ich würde empfehlen, ein reguläres Dateisystem anstelle von Datenbanken zu verwenden. Die Verwendung des Dateisystems ist einfacher als eine Datenbank. Sie können normale Tools für den Zugriff auf Dateien verwenden. Dateisysteme sind für diese Art der Verwendung ausgelegt. NTFS sollte als Speichersystem einwandfrei funktionieren.

Speichern Sie nicht den tatsächlichen Pfad zur Datenbank. Besser ist es, die Sequenznummer des Bildes in der Datenbank zu speichern und eine Funktion zu haben, die aus der Sequenznummer einen Pfad generiert. z.B:

 File path = generatePathFromSequenceNumber(sequenceNumber);

Es ist einfacher zu handhaben, wenn Sie die Verzeichnisstruktur ändern müssen. Möglicherweise müssen Sie die Bilder an einen anderen Ort verschieben, möglicherweise ist der Speicherplatz erschöpft und Sie beginnen, einige der Bilder auf der Festplatte A und einige auf der Festplatte B usw. zu speichern. Es ist einfacher, eine Funktion zu ändern, als die Pfade in der Datenbank zu ändern .

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

  1. Füllen Sie zuerst die laufende Nummer mit führenden Nullen auf, bis Sie mindestens eine 12-stellige Zeichenfolge haben. Dies ist der Name für Ihre Datei. Möglicherweise möchten Sie ein Suffix hinzufügen:
    • 12345 -> 000000012345.jpg
  2. Teilen Sie dann die Zeichenfolge in 2 oder 3 Zeichenblöcke auf, wobei jeder Block eine Verzeichnisebene kennzeichnet. Feste Anzahl von Verzeichnisebenen (zum Beispiel 3):
    • 000000012345 -> 000/000/012
  3. Speichern Sie die Datei unter dem generierten Verzeichnis:
    • Damit der vollständige Pfad und Dateidateinamen für Datei mit Sequenz - ID 123ist 000/000/012/00000000012345.jpg
    • Für Datei mit Sequenz-ID wäre 12345678901234der Pfad123/456/789/12345678901234.jpg

Einige Dinge, die bezüglich Verzeichnisstrukturen und Dateispeicherung zu beachten sind:

  • Mit dem obigen Algorithmus erhalten Sie ein System, bei dem jedes Blattverzeichnis maximal 1000 Dateien enthält (wenn Sie weniger als 1 000 000 000 000 Dateien haben).
  • Es kann Beschränkungen geben, wie viele Dateien und Unterverzeichnisse ein Verzeichnis enthalten kann, zum Beispiel hat das ext3-Dateisystem unter Linux ein Limit von 31998 Unterverzeichnissen pro Verzeichnis.
  • Normale Tools (WinZip, Windows Explorer, Befehlszeile, Bash-Shell usw.) funktionieren möglicherweise nicht sehr gut, wenn Sie über eine große Anzahl von Dateien pro Verzeichnis verfügen (> 1000).
  • Die Verzeichnisstruktur selbst nimmt Speicherplatz in Anspruch, sodass 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 nur den Dateinamen betrachten, falls Sie Ihre Verzeichnisstrukturen durcheinander bringen.
  • Wenn Sie von mehreren Computern aus auf Dateien 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ücken" in der Verzeichnisstruktur. Da Sie jedoch keine Dateien löschen, sollte dies in Ordnung sein.
Juha Syrjälä
quelle
1
sehr interessant! den Dateinamen aufteilen ... daran habe ich nicht gedacht. Ich nehme an, das ist die elegante Art, es zu tun: -?
Am Mittwoch, den
37
Die Verwendung eines Hashes (wie MD5) als Name der Datei sowie der Verzeichnisverteilung würde funktionieren. Die Integrität der Dateien wäre nicht nur ein Nebeneffekt des Benennungsschemas (leicht zu überprüfen), sondern Sie würden auch eine einigermaßen gleichmäßige Verteilung in der gesamten Verzeichnishierarchie erzielen. Wenn Sie also eine Datei mit dem Namen "f6a5b1236dbba1647257cc4646308326.jpg" haben, speichern Sie diese in "/ f / 6" (oder so tief, wie Sie möchten). 2 Ebenen tief ergeben 256 Verzeichnisse oder knapp 4000 Dateien pro Verzeichnis für die ersten 1 Mio. Dateien. Es wäre auch sehr einfach, die Umverteilung auf ein tieferes Schema zu automatisieren.
+1 Mir ist gerade aufgefallen, dass diese Antwort der Antwort ähnlich ist, die ich gerade gepostet habe.
3dinfluence
1
Ich bin definitiv damit einverstanden, das Dateisystem zu verwenden und eine künstliche Kennung zu erstellen, um in Ordnernamen "aufzuschneiden". Sie sollten aber auch versuchen, eine zufällige Verteilung der Bezeichner zu erhalten, dh keine Sequenznummer zu verwenden. Das würde Ihnen einen ausgewogeneren Ordnerbaum ermöglichen. Darüber hinaus können Sie mit der zufälligen Verteilung den Baum einfacher auf mehrere Dateisysteme verteilen. Ich würde auch ein ZFS-basiertes SAN mit aktiviertem Dedup und einem spärlichen Volume für jedes Dateisystem verwenden. Sie können NTFS weiterhin 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. Sie müssen sich auch keine Sorgen machen, dass Sie nicht genügend Nullen
eingeben,
31

Ich werde meine 2 Cent für einen negativen Ratschlag verwenden: Gehen Sie nicht mit einer Datenbank.

Ich arbeite seit Jahren mit Datenbanken zum Speichern von Bildern: große Dateien (1 Mega-> 1 Gigabyte), häufig geändert, mehrere Versionen der Datei, auf die relativ oft zugegriffen wird. Die Datenbankprobleme, auf die Sie beim Speichern großer Dateien stoßen, sind äußerst mühsam zu lösen. Schreib- und Transaktionsprobleme sind knotig und Sie haben Probleme beim Sperren, die zu schweren Zugunglücken führen können. Ich habe mehr Praxis dbcc Skripte in das Schreiben und die Wiederherstellung von Tabellen aus Backups als jeder normale Mensch sollte jemals haben.

Die meisten neueren Systeme, mit denen ich gearbeitet habe, haben den Dateispeicher auf das Dateisystem verschoben und sich lediglich auf die Indizierung von Datenbanken verlassen. Dateisysteme sind für diese Art von Missbrauch ausgelegt, lassen sich viel einfacher erweitern und Sie verlieren selten das gesamte Dateisystem, wenn ein Eintrag beschädigt wird.

Satanicpuppy
quelle
Ja. zur Kenntnis genommen!
mihai
5
Haben Sie sich den Datentyp FILESTREAM in SQL 2008 angesehen? Es ist eine Mischung aus Datenbank- und Dateisystemspeicher.
NotMe
+1 beim Festhalten am Dateiserver statt an einer Datenbank, da Sie schnelle und seltene E / A-Vorgänge ausführen.
Was ist, wenn Sie nur ein paar hundert Dokumente oder Bilder pro Datenbank speichern - ein Nachteil bei der Verwendung der Datenbank für die Speicherung?
Beep Beep
1
+1 ... ein Dateisystem ist sowieso eine Art "Datenbank" (ntfs sicher), also warum sollte es übermäßig kompliziert sein?
Akira
12

Ich denke, die meisten Sites, die sich damit auseinandersetzen müssen, verwenden einen Hash, um sicherzustellen, dass die Dateien gleichmäßig in den Ordnern verteilt werden.

Angenommen, Sie haben einen Hash einer Datei, der in etwa so aussieht. 515d7eab9c29349e0cde90381ee8f810
Sie könnten diesen an folgendem Speicherort speichern und angeben, wie viele Ebenen tief Sie benötigen, um die Anzahl der Dateien in jedem Ordner niedrig zu halten.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

Ich habe diesen Ansatz schon oft erlebt. Sie benötigen weiterhin eine Datenbank, um diese Datei-Hashes einem lesbaren Namen und allen anderen Metadaten zuzuordnen, die Sie speichern müssen. Dieser Ansatz lässt sich jedoch recht gut skalieren, da Sie den Hash-Adressraum auf mehrere Computer und / oder Speicherpools usw. verteilen können.

3deinfluss
quelle
2
Git verwendet einen ähnlichen Ansatz: git-scm.com/book/en/v2/Git-Internals-Git-Objects (um diese Antwort zu
sichern
11

Im Idealfall sollten Sie einige Tests für zufällige Zugriffszeiten für verschiedene Strukturen ausführen, da Ihre spezifische Festplattenkonfiguration, das Caching, der verfügbare 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 brennen Sie.

Z.B,

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

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

Sie sollten auch die Deaktivierung von Dateisystemfunktionen prüfen, die Sie nicht benötigen (z. B. die letzte Zugriffszeit). http://www.pctools.com/guides/registry/detail/50/

Jason Yanowitz
quelle
3
+1 zum Deaktivieren der Generierung von 8.3-Dateinamen und der letzten Zugriffszeit; Das war das erste, was mir einfiel, als ich "Unmengen von [Dateien]" und "NTFS" (Windows) las.
Rob
Link down ........................
Pacerier
7

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 mit Ordnern der obersten Ebene mit einem Buchstaben erstellen, in denen sich weitere Unterordner für den zweiten Buchstaben von Bildern usw. befinden.

Damit:

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

Sie können Ihre eigene erforderliche Tiefe eingeben.

Das Tolle an dieser Lösung ist, dass die Verzeichnisstruktur wie eine Hashtabelle / ein Wörterbuch wirkt. Wenn Sie einen Bilddateinamen angeben, kennen Sie dessen Verzeichnis, und wenn Sie ein Verzeichnis angeben, kennen Sie eine Teilmenge der Bilder, die dort abgelegt werden.

Wim Hollebrandse
quelle
\ a \ b \ c \ d \ e \ f \ Ich mache jetzt, ich dachte, es gibt eine kluge Möglichkeit, dies zu tun.
Am Mittwoch, den
1
Dies ist eine allgemein akzeptierte Lösung für die physische Aufbewahrung. Das eindeutige Generieren der Bild-URLs kann auf einfache Weise dynamisch basierend auf dem Bilddateinamen erfolgen. Außerdem können Sie zur Beschleunigung der Ladezeiten img-a- und img-b-Subdomänen auf dem Imageserver einrichten.
2
Und +1 für "nicht alle in einem Verzeichnis speichern". Ich unterstütze ein Legacy-System, das über 47000 Dateien auf einem Server in einem einzigen Ordner gespeichert hat. Es dauert ungefähr eine Minute, bis der Explorer den Ordner öffnet.
Mark Ransom
5
Durch das Ausführen von a \ b \ c \ d \ e \ f \ g wird die Verzeichnisstruktur sehr tief und jedes Verzeichnis enthält nur wenige Dateien. Verwenden Sie besser mehr als einen Buchstaben pro Verzeichnisebene, z. B. ab \ cd \ ef \ oder abc \ def \. Verzeichnisse belegen auch Speicherplatz auf der Festplatte, sodass Sie nicht zu viele davon benötigen.
Juha Syrjälä
2
Ich musste eine Anwendung unterstützen, die über 4 Millionen Dateien in einem Verzeichnis hatte. es funktionierte überraschend gut, aber man konnte NIEMALS den Explorer dazu bringen, den Ordner zu öffnen, da die neuen Elemente ständig sortiert würden. +1 für NTFS, die damit umgehen können, ohne zu sterben.
SqlACID
5

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 Web 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 mir auch Haystack von Facebook ansehen, sie haben eine sehr gute Lösung zum Speichern und Servieren von Bildern.

Auch wenn Sie das Dateisystem auswählen, müssen Sie diese Dateien mit Verzeichnissen partitionieren. Ich habe mir dieses Problem angeschaut und eine Lösung vorgeschlagen, die aber keineswegs perfekt ist. Ich partitioniere nach Hash-Tabelle und Benutzer können mehr auf meinem Blog lesen .

Lukasz
quelle
Die Bilder sind nicht für den häufigen Zugriff gedacht. damit gibt es kein problem. Ihre Zahl wird sehr schnell wachsen. Ich gehe davon aus, dass es die 1mil sein wird. Mark in 1 Monat.
Am Mittwoch, den
Ich bin in der Programmierer Sicht interessiert , so dass ich diese überdenken nicht zu viel
s.mihai
Wenn Sie also keinen schnellen Zugriff benötigen, ist Haystack wahrscheinlich nichts für Sie. Aus meiner Sicht ist die Verwendung von Verzeichnissen für Partitionen die einfachste Lösung.
Lukasz
5

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 umgekehrten Benennungssystems gespeichert, wobei die Ordnernamen aus der letzten Ziffer der Datei, der letzten 1 usw. generiert werden. Beispiel: 000001234.jpg wird in einer Verzeichnisstruktur wie 4 \ 3 \ 2 \ 1 \ 000001234.jpg gespeichert.

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


quelle
4

Kurz gesagt, Sie müssen keinen Dateipfad in Ihrer Datenbank speichern. Sie können nur einen numerischen Wert speichern, wenn Ihre Dateien so benannt sind, wie Sie es beschreiben. Wenn Sie dann eines der bereits besprochenen genau definierten Speicherschemata verwenden, können Sie den Index als Zahl abrufen und die Datei sehr schnell finden, indem Sie die Verzeichnisstruktur durchlaufen.

Mr. Boy
quelle
: -? Guter schneller Punkt. Nur, dass ich jetzt keinen Algorithmus zum Generieren des Pfades habe.
mihai
4

Müssen Ihre Bilder eindeutig benannt werden? Kann der Prozess, der diese Bilder generiert, denselben Dateinamen mehr als einmal erzeugen? Schwer zu sagen, ohne zu wissen, auf welchem ​​Gerät der Dateiname erstellt wird, aber zu sagen, dass das Gerät zurückgesetzt wird. Beim Neustart werden die Bilder so benannt wie beim letzten Zurücksetzen.

Außerdem sagen Sie, dass Sie in einem Monat 1 Million Bilder erzielen werden. Wie wäre es danach? Wie schnell füllen diese Bilder weiterhin das Dateisystem? Werden sie sich irgendwann auffüllen und sich auf ungefähr 1 Million GESAMT-Bilder ausgleichen, oder wird es Monat für Monat weiter wachsen und wachsen?

Ich frage, weil Sie Ihr Dateisystem nach Monat und dann nach Bild entwerfen könnten. Ich könnte vorschlagen, dass Sie die Bilder in einer solchen Verzeichnisstruktur speichern:

imgs\yyyy\mm\filename.ext

where: yyyy = 4 digit year
         mm = 2 digit month

example:  D:\imgs\2009\12\aaa0001.jpg
          D:\imgs\2009\12\aaa0002.jpg
          D:\imgs\2009\12\aaa0003.jpg
          D:\imgs\2009\12\aaa0004.jpg
                   |
          D:\imgs\2009\12\zzz9982.jpg
          D:\imgs\2010\01\aaa0001.jpg (this is why I ask about uniqueness)
          D:\imgs\2010\01\aab0001.jpg

Monat, Jahr und sogar Tag sind für Sicherheitsbilder geeignet. Ich bin mir nicht sicher, ob Sie das tun, aber ich habe das mit einer Heimsicherheitskamera gemacht, die alle 10 Sekunden ein Foto aufgenommen hat ... Auf diese Weise kann Ihre Anwendung einen Drilldown auf eine bestimmte Zeit oder sogar auf einen Bereich durchführen, in dem das Bild möglicherweise generiert wurde . Oder gibt es anstelle von Jahr und Monat eine andere "Bedeutung", die aus der Bilddatei selbst abgeleitet werden kann? Einige andere Deskriptoren als das von mir angegebene Datumsbeispiel?

Ich würde die Binärdaten nicht in der DB speichern. Hatte noch nie gute Leistung / Glück mit so etwas. Kann mir nicht vorstellen, dass es mit 1 Million Bildern gut funktioniert. Ich würde den Dateinamen speichern und das ist es. Wenn es sich bei allen um JPG handelt, speichern Sie die Erweiterung nicht einmal. Ich würde eine Steuertabelle erstellen, in der ein Zeiger auf den Server, das Laufwerk, den Pfad usw. der Datei gespeichert ist. Auf diese Weise können Sie diese Bilder in eine andere Box verschieben und sie dennoch suchen. Müssen Sie Ihre Bilder mit Stichwörtern versehen? Wenn ja, sollten Sie die entsprechenden Tabellen erstellen, die diese Art der Kennzeichnung ermöglichen.

Sie / Andere haben diese Ideen vielleicht angesprochen, während ich antwortete. Hoffe, das hilft.

Taptronic
quelle
1. Alle Dateien werden eindeutig benannt. 2. Das System wächst und wächst zuerst um 1-mil-Bilder und wächst dann mit einer Rate von einigen Zehntausenden pro Monat. 3. Irgendwann wird es eine Art Tagging der Dateien geben. Deshalb möchte ich eine Art Identifikationsdaten in der Datenbank speichern.
Am Mittwoch, den
3

Ich bin an einem Projekt beteiligt, in dem im Laufe eines Jahres 8,4 Millionen Bilder gespeichert werden, um den Status verschiedener Geräte zu dokumentieren. Auf neuere Bilder wird häufiger zugegriffen, und ältere Bilder werden selten gesucht, es sei denn, es wurde ein Zustand festgestellt, der jemanden zum Stöbern in den Archiven aufforderte.

Ausgehend von dieser Verwendung bestand meine Lösung darin, die Bilder schrittweise in komprimierte Dateien zu komprimieren. Bei den Bildern handelt es sich um JPGs mit jeweils ca. 20 KB und wenig Komprimierung. Das ZIP-Komprimierungsschema ist also keines. Dies geschieht lediglich, um sie zu einem Dateisystemeintrag zu verknüpfen, was NTFS in Bezug auf die Geschwindigkeit beim Verschieben von Laufwerk zu Laufwerk oder beim Durchsuchen der Dateiliste erheblich erleichtert.

Bilder, die älter als ein Tag sind, werden zu einem "täglichen" Reißverschluss zusammengefasst. Reißverschlüsse, die älter als ein Monat sind, werden zu ihrem jeweiligen "monatlichen" Reißverschluss zusammengefasst. und schließlich wird etwas über ein Jahr nicht mehr benötigt und folglich gelöscht.

Dieses System funktioniert gut, da Benutzer die Dateien durchsuchen können (entweder über das Betriebssystem oder eine Reihe von Clientanwendungen) und alle Namen auf der Grundlage von Gerätenamen und Zeitstempeln vergeben werden. Im Allgemeinen kennt ein Benutzer diese beiden Informationen und kann jedes der Millionen Bilder schnell finden.

Ich verstehe, dass dies wahrscheinlich nicht mit Ihren speziellen Details zusammenhängt, aber ich dachte, ich würde teilen.

JYelton
quelle
2

Möglicherweise ein auf dem Erstellungsdatum basierendes Namensschema - entweder mit allen Informationen im Dateinamen oder (besser zum späteren Durchsuchen) Aufteilen in Verzeichnisse. Folgendes kann ich mir vorstellen, je nachdem, wie oft Sie Bilder generieren:

  • Mehrere Bilder pro Tag generiert: Year/Month/Day/Hour_Minute_Second.png
  • Ein paar im Monat: Year/Month/Day_Hour_Minute_Second.png

usw. Du verstehst meinen Standpunkt ... =)

Tomas Aschan
quelle
Sie werden im Laufe der Zeit nicht kontinuierlich generiert, daher werden einige Ordner fett und andere bleiben ... schlank :))
mihai
Sie müssen natürlich nicht jeden Ordner erstellen , nur weil Sie diesem Schema folgen. Sie könnten sogar Year/Month/Day/Hour/Minuteentscheiden, wie viele Ordnerebenen Sie benötigen, je nachdem, wie oft die Bilder generiert werden, wenn die Rate am höchsten ist, und dann einfach keine Ordner erstellen, die leer bleiben würden.
Tomas Aschan
2

Ich würde gerne eine datumsbasierte Ordnerstruktur erstellen, z. B. \ Jahr \ Monat \ Tag, und Zeitstempel für die Dateinamen verwenden. Falls erforderlich, können die Zeitstempel eine zusätzliche Zählerkomponente enthalten, wenn die Bilder so schnell erstellt werden sollen, dass es innerhalb einer Millisekunde mehr als eins geben kann. Durch die Verwendung einer höchstwertigen bis niedrigstwertigen Reihenfolge für die Benennungssortierung werden das Auffinden und die Wartung zum Kinderspiel. zB hhmmssmm [seq] .jpg

John Gardeniers
quelle
2

Erwägen Sie eine Notfallwiederherstellung?

Einige der hier vorgeschlagenen Lösungen führen dazu, dass der Dateiname unleserlich wird (sodass Sie beim Verschieben der physischen Datei den Überblick verlieren, um welche Datei es sich tatsächlich handelt). Ich empfehle, einen eindeutigen physischen Dateinamen beizubehalten, damit Sie Ihre Master-Liste der Dateispeicherorte mit einer kleinen Shell, äh, Powershell, Skript neu generieren können, wenn sie beschädigt ist.

Nach dem, was ich hier gelesen habe, klingt es so, als würden alle diese Dateien in einem Dateisystem gespeichert. Ziehen Sie in Betracht, sie über mehrere Dateisysteme auf mehreren Computern zu speichern. Wenn Sie über die Ressourcen verfügen, legen Sie fest, dass jedes Dateisystem auf zwei verschiedenen Computern gespeichert wird, falls die Stromversorgung ausfällt und der Austausch zwei Tage dauert.

Überlegen Sie, welche Arten von Prozeduren Sie erstellen müssen, um Dateien zwischen Computern oder Dateisystemen zu migrieren. Die Möglichkeit, dies mit Ihrem System zu tun, ist live und online und erspart Ihnen möglicherweise beträchtliche Kopfschmerzen.

Sie können eine GUID als physischen Dateinamen anstelle einer inkrementellen Nummer verwenden, falls Ihr inkrementeller Nummernzähler (die Datenbankidentitätsspalte?) Durcheinander gerät.

Erwägen Sie gegebenenfalls die Verwendung eines CDN wie Amazon S3.

Donald Byrd
quelle
2

Obwohl ich noch keine Bilder in dieser Größenordnung geliefert habe, habe ich bereits eine kleine Galerie-App geschrieben, mit der ~ 25.000 Bilder auf einer 400-MHz-Maschine geliefert werden können. 512 MB RAM oder so. Einige Erfahrungen;

  • Vermeiden Sie auf jeden Fall relationale Datenbanken. Obwohl Datenbanken zweifellos klug im Umgang mit Daten sind, sind sie nicht für eine solche Verwendung ausgelegt (wir haben spezielle hierarchische Schlüsselwert-Datenbanken für das sogenannte Dateisystem ). Ich habe zwar nichts weiter als eine Ahnung, aber ich würde wetten, dass der DB-Cache aus dem Fenster geht, wenn Sie wirklich große Blobs darauf werfen. Während sich meine verfügbare Hardware im kleinen Bereich befand, führte das Nichtberühren der DB bei der Image-Suche zu einer schnelleren Verarbeitung.

  • Untersuchen Sie, wie sich das Dateisystem verhält. Bei ext3 (oder war es zu diesem Zeitpunkt ext2 - kann mich nicht erinnern) lag die Grenze für die effiziente Suche nach Unterverzeichnissen und Dateien bei 256; so dass nur so viele Dateien und Ordner in einem bestimmten Ordner. Wieder spürbare Beschleunigung. Ich kenne NTFS zwar nicht, aber solche Dinge wie XFS (das, soweit ich mich erinnere, B-Trees verwendet) sind extrem schnell, einfach weil sie extrem schnell nachschlagen können.

  • Verteilen Sie die Daten gleichmäßig. Als ich mit dem oben genannten experimentierte, versuchte ich, die Daten gleichmäßig über alle Verzeichnisse zu verteilen (ich habe ein MD5 der URL erstellt und das für Verzeichnisse verwendet; /1a/2b/1a2b...f.jpg). Auf diese Weise dauert es länger, die vorhandene Leistungsgrenze zu erreichen (und der Dateisystem-Cache ist bei so großen Datenmengen ohnehin nicht mehr gültig). (Im Gegensatz dazu möchten Sie vielleicht frühzeitig sehen, wo die Grenzen liegen. Dann möchten Sie alles in das erste verfügbare Verzeichnis werfen.

Morten Siebuhr
quelle
2

Könnte zu spät ins Spiel kommen. Aber eine Lösung (wenn es zu Ihrem Anwendungsfall passt) könnte das Hashing von Dateinamen sein. Auf diese Weise können Sie einen leicht reproduzierbaren Dateipfad unter Verwendung des Dateinamens erstellen und gleichzeitig eine gut verteilte Verzeichnisstruktur erstellen. Beispielsweise können Sie die Bytes des Hashcodes des Dateinamens als Pfad verwenden:

String fileName = "cat.gif";
int hash = fileName.hashCode();
int mask = 255;
int firstDir = hash & mask;
int secondDir = (hash >> 8) & mask;

Dies würde zu folgendem Pfad führen:

/172/029/cat.gif

Sie können dann cat.gifin der Verzeichnisstruktur finden, indem Sie den Algorithmus reproduzieren.

Die Verwendung von HEX als Verzeichnisnamen ist so einfach wie das Konvertieren der intWerte:

String path = new StringBuilder(File.separator)
        .append(String.format("%02x", firstDir))
        .append(File.separator)
        .append(String.format("%02x", secondDir)
        .toString();

Ergebend:

/AC/1D/cat.gif

Ich habe vor ein paar Jahren einen Artikel darüber geschrieben und ihn kürzlich auf Medium verschoben. Es enthält einige weitere Details und einen Beispielcode: Dateinamen-Hashing: Erstellen einer Hash-Verzeichnisstruktur . Hoffe das hilft!

Michael Andrews
quelle
Wir lagern 1,8 Milliarden Artikel mit etwas Ähnlichem. Es funktioniert gut. Verwenden Sie einen Hash, der schnell ist und niedrige Kollisionsraten aufweist.
CVVS
1

Wenn sie nicht sofort benötigt werden und Sie sie sofort generieren können und es sich um kleine Images handelt, warum nicht einen LRU-Speicher- oder Festplatten-Cache über Ihrem Image-Generator implementieren?

Dies könnte Sie aus dem Speicher retten und die zu liefernden Bilder von mem fernhalten?

Jé Queue
quelle
1

Ich habe gerade einen Test auf zfs ausgeführt, weil ich zfs liebe und ich hatte eine 500gig-Partition, auf der ich Komprimierung hatte. Ich habe ein Skript geschrieben, das 50-100k-Dateien generiert und in verschachtelte Verzeichnisse 1/2/3/4/5/6/7/8 (5-8 Ebenen tief) gestellt hat, und ich habe es 1 Woche laufen lassen. (Es war kein großartiges Skript.) Es füllte die Festplatte und hatte ungefähr 25 Millionen Dateien. Der Zugriff auf eine Datei mit einem bekannten Pfad war sofort möglich. Das Auflisten eines Verzeichnisses mit einem bekannten Pfad erfolgte sofort.

Das Abrufen der Dateiliste (über find) dauerte 68 Stunden.

Ich habe auch einen Test durchgeführt, bei dem viele Dateien in einem Verzeichnis abgelegt wurden. Ich habe bis zu 3,7 Millionen Dateien in einem Verzeichnis gespeichert, bevor ich aufgehört habe. Das Auflisten des Verzeichnisses, um eine Zählung zu erhalten, dauerte ungefähr 5 Minuten. Das Löschen aller Dateien in diesem Verzeichnis dauerte 20 Stunden. Die Suche und der Zugriff auf alle Dateien erfolgten jedoch sofort.

Stu
quelle
1

Ich sehe andere, die eine Datenbank erwähnen, aber sehe keine Erwähnung davon in deinem Beitrag. In jedem Fall ist meine Meinung zu diesem speziellen Punkt: entweder bei einer Datenbank oder einem Dateisystem bleiben. Wenn Sie beides mischen müssen, seien Sie vorsichtig. Die Dinge werden komplizierter. Aber vielleicht musst du. Das Speichern von einer Million Fotos in einer Datenbank ist keine gute Idee.

Die folgenden Spezifikationen könnten Sie interessieren, die meisten Digitalkameras verwenden sie, um die Dateispeicherung zu verwalten: https://en.wikipedia.org/wiki/Camera_Image_File_Format

Im Wesentlichen wird ein Ordner erstellt, z. B. 000OLYMPUSund diesem Ordner werden Fotos hinzugefügt DSC0000.RAW. Wenn der Dateinamenszähler DSC9999.RAWeinen neuen Ordner erreicht, wird ein neuer Ordner erstellt ( 001OLYMPUS) und das Bild erneut hinzugefügt, wobei der Zähler zurückgesetzt wird, möglicherweise mit einem anderen Präfix (Beispiel:) P_0000.RAW.

Alternativ können Sie auch Ordner erstellen, die auf Teilen des Dateinamens basieren (bereits mehrmals erwähnt). Wenn Ihr Foto beispielsweise einen Namen hat IMG_A83743.JPG, speichern Sie es unter IMG_\A8\3\IMG_A83743.JPG. Die Implementierung ist komplizierter, erleichtert jedoch das Auffinden Ihrer Dateien.

Abhängig vom Dateisystem (dies erfordert einige Nachforschungen) können Sie möglicherweise alle Bilder in einem einzigen Ordner sichern, dies führt jedoch meiner Erfahrung nach normalerweise zu Leistungsproblemen.

Rolf
quelle
0

Vielleicht möchten Sie sich ZFS (Dateisystem, Volume Manager von Sun) ansehen


quelle
0

Eine saubere Möglichkeit, den Pfad aus einer großen Zahl zu generieren, besteht darin, ihn einfach in Hex zu konvertieren und ihn dann zu teilen!

zB 1099496034834> 0xFFFF1212>FF/FF/12/12

public string GeneratePath(long val)
{  
    string hex = val.ToString("X");
    hex=hex.PadLeft(10, '0');
    string path="";
    for(int i=0; i<hex.Length; i+=2 )
    {
        path += hex.Substring(i,2);
        if(i+2<hex.Length)
            path+="/";
    }
    return path;
}

Speichern und laden:

public long Store(Stream doc)
{
   var newId = getNewId();
   var fullpath = GeneratePath(newId)
   // store into fullpath 
   return newId;
}

public Stream Load(long id)
{
   var fullpath = GeneratePath(newId)
   var stream = ... 
   return stream;
}

Vollständige Quellcodes: https://github.com/acrobit/AcroFS

Ghominejad
quelle
-1

Leider sind Dateisysteme sehr schlecht (Leistung mit vielen Dateien pro Verzeichnis oder tiefen Verzeichnisbäumen, Überprüfungszeiten beim Neustart, Zuverlässigkeit) beim Verwalten vieler kleiner Dateien. Daher ist die obige Lösung mit ZIP-Dateien die beste, wenn Sie ein Dateisystem verwenden möchten.

Die Verwendung eines Datenbankmanagers ist bei weitem die beste Option. ein einfaches wie BDB oder GDBM zum Beispiel; Sogar ein relationales DBMS wie MySQL wäre besser. Nur faule Leute, die Dateisysteme und Datenbanken nicht verstehen (z. B. diejenigen, die Transaktionen abweisen), neigen dazu, Dateisysteme als Datenbanken zu verwenden (oder etwas seltener umgekehrt).


quelle
-2

Wie wäre es mit einer Datenbank mit einer Tabelle, die eine ID und ein BLOB enthält, um das Bild zu speichern? Anschließend können Sie jederzeit neue Tabellen hinzufügen, wenn Sie einem Foto weitere Datenelemente zuordnen möchten.

Wenn Sie eine Skalierung erwarten, warum nicht jetzt skalieren? Sie sparen jetzt und später Zeit IMO. Implementieren Sie die Datenbankschicht einmal, was zunächst recht einfach ist. Oder implementieren Sie etwas mit Ordnern und Dateinamen und bla bla bla und wechseln Sie später zu etwas anderem, wenn Sie MAX_PATH in die Luft jagen.

jdmichal
quelle
5
Wäre dort gewesen, hätte die Narben, um es zu beweisen. Datenbanken, in denen Bilder in großer Anzahl gespeichert sind, sind kaum zu glauben und erfordern einen übermäßigen Wartungsaufwand. Es ist viel besser, sie im Dateisystem zu speichern, es sei denn, Sie haben ein bestimmtes Bedürfnis, das nur von einer Datenbank beantwortet werden kann (unser Versions-Tracking).
Satanicpuppy
1
Und es gibt viele Dienstprogramme für den Umgang mit Dateien und Dateisystemen, wenige bis keine für den Umgang mit Dateien in einer Datenbank.
Mark Ransom
2
Oh Gott Nein. Bitte verwenden Sie keine Datenbank als großen BLOB-Speicher.
Neil N
Eek. Wusste nicht, dass Datenbanken (noch?) So viele Probleme mit BLOBs haben.
Wie kann so eine schlechte Lösung, die so viele Kommentare hat, noch eine +1 haben? Keine Beleidigung für das OP (ich sehe, dass es von SO kam), aber der Downvote-Button ist aus einem bestimmten Grund hier!
Mark Henderson