Der beste Weg, um viele Dateien auf der Festplatte zu speichern

8

Ich konnte keinen guten Titel für die Frage finden, das ist es, was ich versuche zu tun:

  • Dies ist eine .NET-Anwendung.
  • Ich muss bis zu 200000 Objekte speichern (zwischen 3KB-500KB)
  • Ich muss ungefähr 10 davon pro Sekunde aus mehreren Threads speichern
  • Ich verwende binäreSerialisierung, bevor ich sie speichere
  • Ich muss später auf eine ganzzahlige, eindeutige ID
  • zugreifen

Was ist der beste Weg, dies zu tun?

  • Ich kann sie nicht im Gedächtnis behalten, da ich Erinnerungen ausmerzen werde
  • Wenn ich sie auf der Festplatte als separate Dateien abspeichere, was sind die möglichen Leistungsprobleme? Würde es die Gesamtleistung stark verringern?
  • Soll ich eine Art Caching implementieren, zum Beispiel 100 Objekte kombinieren und einmal als eine Datei schreiben. Dann analysiere sie später. Oder etwas ähnliches?
  • Soll eine Datenbank verwendet werden? (Zugriffszeit ist nicht wichtig, es wird keine Suche geben und ich werde nur ein paar Mal auf die bekannte eindeutige ID zugreifen). Theoretisch brauche ich keine Datenbank, ich möchte das nicht komplizieren.

UPDATE:

  • Ich nehme an, die Datenbank wäre langsamer als das Dateisystem, beweisen Sie mich falsch, wenn Sie etwas darüber haben. Deshalb lehne ich mich auch dem Dateisystem zu. Aber was ich wirklich besorgt bin, ist das Schreiben von 200KB * 10 pro Sekunde auf die Festplatte ( dies kann jede Festplatte sein, ich kontrolliere keine Hardware, es ist ein Desktop-Tool, das in verschiedenen Systemen eingesetzt wird ) .
  • Wenn ich ein Dateisystem verwende, werde ich Dateien in separaten Ordnern speichern, um Probleme mit dem Dateisystem zu vermeiden (, damit Sie diese Einschränkung ignorieren können
  • )
dr. evil 09.02.2010, 14:51
quelle

8 Antworten

3

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.

    
0xfe 09.02.2010, 15:05
quelle
2

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.

    
Martin Beckett 09.02.2010 15:02
quelle
2

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%     
Nthalk 17.10.2011 17:10
quelle
1

Sie können mongoDb auschecken, es unterstützt Geschäftsdateien.

    
Benny 09.02.2010 15:05
quelle
0

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:

  1. Machen Sie eine Klasse, die sich mit dem Speichern und Abrufen befasst (damit Sie später diese Klasse ändern können und nicht jeden Punkt in Ihrer Anwendung, der sie verwendet)
  2. Speichern Sie die Dateien auf der Festplatte so wie sie sind, kombinieren Sie sie nicht
  3. Verteilen Sie sie über Unterverzeichnisse, wobei Sie in jedem Verzeichnis 1000 oder weniger Dateien behalten (der Verzeichniszugriff erhöht den Aufwand, wenn Sie viele Dateien in einem einzigen Verzeichnis haben)
quelle
0

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.

    
Rex Kerr 09.02.2010 15:22
quelle
0

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.

    
Jason 09.02.2010 15:56
quelle
0

in Ihrem Fall memached können einige Leistungsprobleme abdecken.

    
ehsan 05.07.2011 07:10
quelle

Tags und Links