Ich konnte keinen guten Titel für die Frage finden, das ist es, was ich versuche zu tun:
Was ist der beste Weg, dies zu tun?
UPDATE:
Wenn Sie die Verwendung einer Datenbank vermeiden möchten, können Sie sie als Dateien auf der Festplatte speichern (um die Dinge einfach zu halten). Sie müssen jedoch bei der Verwaltung einer großen Anzahl von Dateien in einem einzigen Verzeichnis auf Dateisystemüberlegungen achten.
Viele gebräuchliche Dateisysteme verwalten ihre Dateien pro Verzeichnis in einer Art sequentieller Liste (z. B. einfach Dateizeiger oder Inodes nacheinander oder in verknüpften Listen speichern.) Dadurch werden Dateien geöffnet, die sich im unteren Bereich befinden Die Liste ist wirklich langsam.
Eine gute Lösung besteht darin, Ihr Verzeichnis auf eine kleine Anzahl von Knoten zu beschränken (sagen wir n = 1000) und eine Baumstruktur von Dateien unter dem Verzeichnis zu erstellen.
Also statt Dateien wie folgt zu speichern:
/ Verzeichnis / Datei1 / Verzeichnis / Datei2 / Verzeichnis / Datei3 ... / Verzeichnis / DateiN
Speichere sie als:
/ dir / r1 / s2 / Datei1 / Verzeichnis / r1 / s2 / Datei2 ... / Verzeichnis / rM / sN / DateiP
Indem Sie Ihre Dateien auf diese Weise aufteilen, verbessern Sie die Zugriffszeit in den meisten Dateisystemen erheblich.
(Beachten Sie, dass es einige neue Dateisysteme gibt, die Knoten in Bäumen oder andere Formen der Indexierung darstellen. Diese Technik funktioniert auch bei diesen.)
Weitere Überlegungen sind die Optimierung Ihres Dateisystems (Blockgrößen, Partitionierung usw.) und Ihres Puffercaches, damit Sie eine gute Datenlokalität erhalten. Abhängig von Ihrem Betriebssystem und Dateisystem gibt es viele Möglichkeiten dies zu tun - Sie müssen wahrscheinlich nachsehen.
Alternativ können Sie auch eine eingebettete Datenbank wie SQLlite oder Firebird verwenden, wenn dies nicht ausreicht.
HTH.
Ich wäre versucht, eine Datenbank zu verwenden, in C ++ entweder sqlite oder coucheDB.
Diese würden beide in .Net funktionieren, aber ich weiß nicht, ob es eine bessere .Net spezifische Alternative gibt.
Selbst bei Dateisystemen, die 200.000 Dateien in einem Verzeichnis verarbeiten können, wird es immer nötig sein, das Verzeichnis
zu öffnen Bearbeiten - Die DB wird wahrscheinlich schneller sein!
Das Dateisystem ist nicht für eine große Anzahl von kleinen Objekten ausgelegt, die DB ist.
Es wird alle Arten von cleveren Caching- / Transaktionsstrategien implementieren, an die Sie nie gedacht haben.
Es gibt Fotosites, die das Dateisystem über eine Datenbank ausgewählt haben. Aber sie machen hauptsächlich Lesevorgänge auf größeren Blobs und sie haben viele Admins, die Experten darin sind, ihre Server auf diese spezielle Anwendung abzustimmen.
Ich empfehle, eine Klasse zu erstellen, die eine einzige Thread-Warteschlange zum Ablegen von Bildern (gziped) am Ende einer Datei hat und dann die Datei-Offsets / Meta-Informationen in einer kleinen Datenbank wie sqlite speichert. Dies ermöglicht es Ihnen, alle Ihre Dateien schnell und sicher aus mehreren Threads zu speichern und sie effizient und ohne jegliche Dateisystem-Macken (außer max filesize) zu lesen, was mit zusätzlichen Metadaten erledigt werden kann.
%Vor%Die einzige Möglichkeit, um sicher zu sein, wäre, mehr über Ihr Nutzungsszenario zu erfahren.
Wird zum Beispiel die Verwendung der Dateien später in Clustern von 100 Dateien benötigt? Vielleicht wäre es sinnvoll, sie zu kombinieren.
In jedem Fall würde ich versuchen, zunächst eine einfache Lösung zu erstellen und sie nur dann zu ändern, wenn Sie später feststellen, dass Sie ein Leistungsproblem haben.
Folgendes würde ich tun:
Ich benutze .NET eigentlich nicht, also bin ich mir nicht sicher, was dort einfach ist, aber im Allgemeinen würde ich zwei Ratschläge anbieten.
Wenn Sie viel schreiben und selten lesen müssen (z. B. Protokolldateien), sollten Sie eine ZIP-Datei oder ähnliches erstellen (wählen Sie eine Komprimierungsstufe, die die Leistung nicht zu sehr verlangsamt; in der Bewertung 1-9) , 5 oder so funktioniert normalerweise für mich). Das bringt Ihnen mehrere Vorteile: Sie treffen das Dateisystem nicht so hart, Ihr Speicherplatz wird reduziert, und Sie können natürlich Dateien in Blöcken von 100 oder 1000 gruppieren oder was auch immer.
Wenn Sie viel und viel lesen müssen, können Sie Ihr eigenes flaches Dateiformat definieren (es sei denn, Sie haben Zugriff auf Dienstprogramme zum Lesen und Schreiben von .tar-Dateien oder Ähnlichem oder zum Cheaten und binäre Daten in ein 8-Bit-Graustufen-TIFF setzen. Definieren Sie Datensätze für jeden Header - möglicherweise 1024 Bytes, die jeweils den Offset in die Datei und den Dateinamen und alles, was Sie sonst noch speichern müssen, enthalten - und schreiben Sie die Daten dann in Chunks. Wenn Sie einen Chunk lesen müssen, lesen Sie zuerst die Kopfzeile (vielleicht 100k) und dann springen Sie zu dem Offset, den Sie benötigen, und lesen Sie den Betrag, den Sie benötigen. Der Vorteil von Kopfzeilen mit fester Größe ist, dass Sie zu Beginn leere Daten in sie schreiben können und dann einfach neue Daten an das Ende der Datei anhängen und dann zurückgehen und den entsprechenden Datensatz überschreiben.
Schließlich könnten Sie vielleicht in etwas wie HDF5 schauen; Ich weiß nicht, was die .NET-Unterstützung dafür ist, aber es ist eine gute Möglichkeit, generische Daten zu speichern.
Sie könnten den Caching-Anwendungsblock von Microsoft in Erwägung ziehen. Sie können es so konfigurieren, dass es IsolatedStorage als Sicherungsspeicher verwendet, sodass Elemente im Cache serialisiert werden. Leistung könnte ein Problem sein - ich denke, dass sie bei Schreibvorgängen aus der Box heraus blockt, also müssen Sie sie vielleicht optimieren, um stattdessen asynchrone Schreibvorgänge auszuführen.
Tags und Links memory .net performance storage