Die beste Weg zum Speichern / Abrufen von Millionen von Dateien, wenn ihre Meta-Daten in einer SQL-Datenbank

StackOverflow https://stackoverflow.com/questions/1257415

Frage

Ich habe einen Prozess, der zunächst geht um 3-4 Millionen PDF-Dateien zu erzeugen, und mit einer Geschwindigkeit von 80 K / Tag fortgesetzt werden. Sie werden in ziemlich klein (50K) jeden, aber was ich mache mir Sorgen darüber, wie die Gesamtmasse von Dateien verwalten Ich bin für eine einfache Lookup zu erzeugen. Einige Details:

  1. Ich werde ein paar andere Schritte haben einmal eine Datei ausführen generiert wurden, und gibt es ein paar Server teilnehmen, also werde ich für Dateien anzusehen, benötigen, wenn sie erzeugt sind.
  2. Sobald erzeugt, werden die Dateien zwar einen Lookup-Prozess verfügbar sein, die ich geschrieben habe. Im Grunde werde ich brauchen, um sie zu ziehen, auf der Grundlage einer Auftragsnummer, die pro Datei eindeutig ist.
  3. Sie können jederzeit eine bestehende Auftragsnummer kann erneut eingereicht werden, und die erzeugte Datei benötigen die ursprüngliche Kopie zu überschreiben.

Ursprünglich hatte ich diese Dateien alle in einem einzigen Verzeichnis auf einem NAS schreiben geplant, aber ich weiß, das ist keine gute Idee sein könnte, da es Millionen von ihnen sind und Windows möglicherweise nicht eine Million-Datei-Lookup behandeln sehr anmutig. Ich suche nach ein paar Ratschläge:

  1. Ist ein einzelner Ordner in Ordnung? Die Dateien werden nie aufgeführt werden. - sie werden nur mit einem Dateinamen mit einem System.IO.File abgerufen werden Ich habe bereits festgestellt,
  2. Wenn ich einen Ordner tun, kann ich sehen für neue Dateien mit einem System.IO.DirectoryWatcher, auch mit, dass viele Dateien, oder wird es mit, dass viele Dateien träge zu werden beginnen?
  3. Sollten sie als BLOBs in einer SQL Server-Datenbank stattdessen werden gespeichert? Da ich sie von einem Referenzwert abzurufen benötigen, vielleicht dies mehr Sinn macht.

Vielen Dank für Ihre Meinung!

War es hilfreich?

Lösung

Ich würde Gruppe die Dateien in bestimmten Unterordner und versuchen, sie (die Unterordner) in einigen Business-Logik zu organisieren. Vielleicht sind alle Dateien in einem bestimmten Tag gemacht? Während einer sechs Stunden eines jeden Tages? Oder jede Anzahl der Dateien, würde ich ein paar 1000 max sagen. (Es gibt wahrscheinlich eine ideale Zahl gibt, hoffentlich jemand wird es posten.)

Sie älter werden die Dateien immer und gelöscht werden? Wenn ja, Art und Datei löschbar Brocken sein. Wenn nicht, kann ich Ihren Hardwarehersteller sein?

Es gibt Argumente auf beiden Seiten von Dateien in einer Datenbank zu speichern.

  • Auf der einen Seite Sie verbesserte Sicherheit zu bekommen, weil es umständlich ist, die Dateien aus der DB zu ziehen; auf der anderen Seite, können Sie möglicherweise eine schlechtere Leistung bekommen ‚, weil es mehr umständlich ist, die Dateien aus der DB zu ziehen.
  • In der DB, Sie müssen sich nicht darum kümmern, wie viele Dateien pro Ordner, Sektor, NAS-Cluster, was auch immer -, dass das Problem des DB ist, und wahrscheinlich haben sie eine gute Umsetzung für diese bekam. Auf der anderen Seite, wird es schwieriger sein, die Daten zu verwalten / überprüfen, da es eine Unmenge von Blobs in einer einzigen Tabelle sein würde, und, na ja, igitt. (Sie konnten die Tabelle auf der Partition auf Basis-oben genannte Business-Logik, die unendlich viel leichte Löschung oder Archivierung machen würde auszuführen. Das, oder vielleicht partitionierten Ansichten, da die Tabellenpartitionierung eine Grenze von 1000 Partitionen).
  • SQL Server 2008 hat den Filestream-Datentyp; Ich weiß nicht viel darüber, könnte sich lohnen, ein Blick in.

Ein letzter Punkt zu befürchten ist, die Daten „ausgerichtet“ zu halten. Wenn die DB die Informationen über die Datei zusammen mit dem Pfad / Namen in der Datei gespeichert werden, und die Datei verschoben wird, könnte man total abgespritzt bekommen.

Andere Tipps

Ihre Fragen zu beantworten:

  1. Ich würde sie in einem einzigen Ordner nicht speichern. Wie die Chancen irgendwann bist du bei den tatsächlichen Dateien auf der Festplatte suchen, anstatt auf andere Weise will.
    Stattdessen warum speichert sie nicht in separaten Verzeichnissen, aufgeteilt in Chargen von 1000? Möglicherweise mit der ID als Schlüssel.
  2. Dass viele Dateien wahrscheinlich die DirectorWatcher überschwemmen, so werden einige verloren. Ich habe dies in der Vergangenheit verwendet, und an einem bestimmten Punkt (afew hundert), habe ich finde es beginnt Dateien zu verpassen. verwendet möglicherweise ein anderes Verzeichnis für eingehende Dateien und diese dann jeden Prozess so oft. Dies kann dann einen Prozess auslösen, das Original zu aktualisieren.
  3. Ich würde die Dokumente in einer Datenbank nicht speichern, aber auf jeden Fall Speichern von Metadaten in einer Datenbank.

Sie können ganz einfach Dateien in mehreren Ordnern organisieren, ohne dass dies von Business-Logik zu tun zu haben, oder um pro Tag, die, wenn diese Art von Ordnung sein ‚klumpig‘ in (viele Treffer in einem Ordner, nur wenige würden besonders schön ist andere).

Der einfachste Weg dies zu tun ist, einen eindeutigen Hash für die Dateinamen zu erstellen, so dass du vielleicht etwas wie diese:

sf394fgr90rtfofrpo98tx.pdf

Dieses Dann lösen sich in zwei Zeichenblöcke, und Sie werden diese:

sf/39/4f/gr/90/rt/fo/fr/po/98/tx.pdf

Wie Sie sehen können, gibt es Ihnen einen tiefen Verzeichnisbaum, die Sie leicht navigieren können.

Mit einer guten Hash-Funktion, werden diese sehr gleichmäßig verteilt sein, und Sie werden nie mehr als 1.296 Einträge pro Verzeichnis. Wenn Sie jemals eine Kollision bekommen (was äußerst selten sein sollte), fügen Sie einfach eine Nummer zu Ende: tx.pdf, tx_1.pdf, tx_2.pdf. Auch hier Kollisionen auf solche großen Hashes sollte extrem selten sein, so dass die Art der Verklumpung Sie aus diesem Grund bekommen kein Thema sind.

Sie haben gesagt, dass die Dokumente digital signiert sind, so dass Sie wahrscheinlich den Hash haben es Sie müssen direkt in Form der Signatur-String.

1) Ein einfacher Ordner kann mit einem separaten Index in akzeptabler Weise schnell sein, aber wie es ist trivial es in einem Unterverzeichnis zu setzen, die ihnen in der Lage, das zu sehen erlauben würden nur zu tun.
So, jetzt müssen Sie Ihre Namenskonvention herauszufinden. Obwohl ich normalerweise einen Hash würde vorschlagen, eine gleichmäßige Verteilung von IDs zu erhalten, aber wie Sie tun so viel wahrscheinlich macht es Sinn, die Werte zu verwenden, haben Sie schon bekommen. Wenn Sie eine Bestellnummer haben Sie haben einen Zeitstempel zu? Wenn ja, Präfix nur die Bestellnummer mit einem Zeitstempel.

Seien Sie sich bewusst sein, dass, wenn Sie die Bestellung ids verwenden auftreten können http: // en .wikipedia.org / wiki / Benford% 27s_law

Sie müssen es testen. All diese Lösungen sind abhängig von dem zugrunde liegenden Dateisystem. Einige Dateisysteme große Verzeichnisse vergleichen kann, können einige nicht. Einige Dateisysteme Index ihre Verzeichnisse, manche nicht (sind diese beiden Punkte nicht unbedingt im Zusammenhang).

Dinge brechen in einem Baum von Verzeichnissen hat vernünftige Chance performant zu sein, einfach weil, am Ende werden die einzelnen Verzeichnisse wenige Gesamt Einträge zu neigen. Das funktioniert für die meisten jedes Dateisystem, weil sogar eine „dumme“ ein, die eine lineare Verzeichnissuche für die Datei tut ziemlich schnell ein paar hundert Einträge suchen können.

Wenn das Dateisystem die Verzeichnisse indiziert (wie, sagen wir, ein btree oder einfach intern Sortierung, die in diesem Zusammenhang effektiv dasselbe ist), dann die Verzeichnisgrößen sind weniger wichtig, obwohl einige Werkzeuge beschweren kann (ein Laden Windows Explorer-Fenster mit 4M-Dateien, die wissen, was passieren wird).

Also, ich würde Ihr geplantes Betriebssystem und die Dateisystem-Optionen erforschen und testen und sehen, was am besten für Sie.

Bestimmen Sie

einige logische Reihenfolge von Unterverzeichnissen und speichern sie in Blöcken von nicht mehr als 512 oder so Dateien in einem Ordner.

Speichern Sie nicht die Dateien in einer Datenbank. Datenbanken sind für Daten, Dateiserver sind für Dateien. Bewahren Sie sie auf einem Dateiserver, aber speichern Sie den Pfad und Wiedergewinnungsinformationen in einer Datenbank.

Warum bedenken nicht all diese Dateien speichern, nachdem sie in PDF in die DB (blob) umgewandelt Daher Vorteile:

  1. Ich glaube, Sie werden nicht einfach direkt mit dem Betriebssystem zu tun haben I / O, und lassen Sie alles bis zum DB.
  2. Keine Notwendigkeit Hash Benennung
  3. Einfache Sicherung und Wartung

Wenn Sie eine Datenbank mit Dateien zu speichern, insbesondere mit kleiner Datei soll der Aufwand klein sein. Sie können aber auch Dinge wie:

DELETE FROM BLOBTABLE WHERE NAME LIKE '<whatever>'

oder, wenn Sie ein Ablaufdatum haben, oder möchten Sie eine Datei aktualisieren, entfernen Sie es nach:

DELETE FROM BLOBTABLE WHERE CREATIONDATE < ...
etc...

Frage:

Warum diese Dokumente müssen als PDF-Dateien erzeugt und gespeichert werden?

Wenn sie erzeugt werden können, warum hält nicht nur die Daten in der Datenbank und erzeugen sie im Fluge, wenn erforderlich? Dies bedeutet, dass Sie die aktuellen Daten suchen, die für die Suche und sowieso nicht haben, die Dateien auf der Festplatte erforderlich ist. Auf diese Weise können Sie auch die PDF-Vorlage aktualisieren, wenn ohne die Notwendigkeit erforderlich, etwas zu regenerieren?

1) Das geht völlig im Widerspruch zu dem, was ich predige die Regel, aber Sie können sie in einer SQL-Datenbank gespeichert werden sollen, da sie trully kleine Dateien sind. SQL Server würden Sie finden und leicht auch ermöglichen, schnell die gewünschten Dateien ohne verrückt Platten trashing müssen normalerweise mit Aufzählen ein so großes Verzeichnis zugeordnet ist. Auch die Dateien in SQL Speicher (während ich in der Regel gegen bin) würde die Sicherung erheblich erleichtern / Wiederherstellungsprozess.

2) Speichern Sie sie alle in den Verzeichnissen und entweder indizieren sie mit Windows-Indexdienst ( zittert ) oder eine eigene Index in SQL Server erstellen, die den Dateinamen enthalten würde und vollständigen Pfad. Ich würde vorschlagen, sie in separaten Verzeichnissen, mit nur ein paar Zehntausende von Dateien jeder speichern. Vielleicht könnten Sie die Reihenfolge Jahr als Ordnernamen verwenden?

Unabhängig davon, wie ihr gespeicherten - nicht das Verzeichnis scannen, um die Dateien zu finden -. Sie werden auf jeden Fall benötigen Sie einen Index irgendeiner Art haben,

Hope, das hilft!

Meine Datei-Datenbank enthält mehr als 4 Millionen Ordner mit vielen Dateien in jedem Ordner.

Just nur alle Ordner in einem Verzeichnis geworfen. NTFS kann dies ohne Problem umgehen und erweiterte Tools wie Robocopy kann helfen, wenn Sie es verschieben müssen.

So stellen Sie sicher, dass Sie indizieren können die Dateien ohne Scan. Ich tat dies, indem meinem Index in einer MySQL-Datenbank zu werfen.

So eine Datei erhalte ich die MySQL-Datenbank auf einige Metadaten zu suchen und einen Index erhalten. Dann benutze ich diesen Index die Datei direkt zu lesen. Scaled gut für mich so weit. Aber beachten Sie, dass Sie alles, was in dem Direktzugriffs werden drehen und somit zufällige Lese- / schreibt. Dies ist eine schlechte Leistung für HDD, aber zum Glück SSD wird eine Menge helfen.

Außerdem würde ich die Dateien nicht in die MySQL-Datenbank werfen. Sie werden in der Lage zu tun Netzwerk nicht liest, ohne einen Client mit, die MySQL verstehen. Im Moment kann ich jede Datei über das Netzwerk zugreifen jedes Programm mit, weil ich nur sein Netzwerk URL verwenden kann.

Ich denke, wie so viele andere gesagt haben, sollten Sie Unterordner tun, aber in einer Weise, dass Sie die Daten durch den Code zu finden. wenn Datetime funktioniert, verwenden Sie zum Beispiel, dass. Aus der Lektüre, was Sie sagten es scheint, dass es irgendeine Form der hierarchischen Struktur der Berichte ist (täglich, wöchentlich, täglich X-Bericht, stündliche Y Bericht usw.) I an der Struktur aussehen würde, wann und warum die Berichte generiert und bauen meine Verzeichnisse auf diese Weise.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top