8 Stimmen

Skalierbare, schnelle, textdateibasierte Datenbank-Engine?

Ich arbeite mit großen Mengen wissenschaftlicher Daten, die in tab-separierten .tsv-Dateien gespeichert sind. Die typischen Operationen, die durchgeführt werden sollen, sind das Lesen mehrerer großer Dateien, das Filtern bestimmter Spalten/Zeilen, das Verknüpfen mit anderen Datenquellen, das Hinzufügen von berechneten Werten und das Schreiben des Ergebnisses als eine andere .tsv.

Der Klartext wird aufgrund seiner Robustheit, Langlebigkeit und selbsterklärenden Eigenschaften verwendet. Das Speichern der Daten in einem anderen Format ist keine Option, sie müssen offen und einfach zu verarbeiten bleiben. Es gibt viele Daten (Dutzende von TB), und es ist nicht erschwinglich, eine Kopie in eine relationale Datenbank zu laden (wir müssten doppelt so viel Speicherplatz kaufen).

Da ich hauptsächlich Auswahlen und Verknüpfungen durchführe, habe ich festgestellt, dass ich im Grunde genommen eine Datenbank-Engine mit einer .tsv-basierten Speicherung benötige. Mir ist es egal, um Transaktionen, da meine Daten alle einmal geschrieben und oft gelesen werden. Ich muss die Daten vor Ort verarbeiten, ohne einen großen Konvertierungsschritt und Datenklonierung.

Da so viele Daten auf diese Weise abgefragt werden müssen, muss ich sie effizient verarbeiten, indem ich Caching und ein Raster von Computern nutze.

Weiß jemand von einem System, das Datenbank-ähnliche Funktionen bietet, während es plain tab-separierte Dateien als Backend verwendet? Es scheint mir ein sehr generisches Problem zu sein, mit dem praktisch alle Wissenschaftler auf die eine oder andere Weise umgehen müssen.

6voto

Jason S Punkte 178087

Es gibt viele Daten (Zehntel von TBs), und es ist nicht erschwinglich, eine Kopie in eine relationale Datenbank zu laden (wir müssten doppelt so viel Speicherplatz kaufen).

Sie kennen Ihre Anforderungen besser als einer von uns, aber ich würde Ihnen vorschlagen, noch einmal darüber nachzudenken. Wenn Sie 16-Bit-Integer (0-65535) in einer CSV-Datei gespeichert haben, beträgt die Speicherungseffizienz Ihrer .tsv-Datei etwa 33%: Die meisten 16-Bit-Integer plus einem Trennzeichen benötigen 5 Byte, während die nativen Integer 2 Byte benötigen. Für Gleitkommadaten ist die Effizienz noch schlechter.

Ich würde empfehlen, die vorhandenen Daten zu nehmen und anstatt sie roh zu speichern, sie auf folgende zwei Arten zu verarbeiten:

  1. Speichern Sie sie komprimiert in einem bekannten Kompressionsformat (z. B. gzip oder bzip2) auf Ihrem permanenten Archivmedium (Backup-Server, Bandlaufwerke, was auch immer), damit Sie die Vorteile des .tsv-Formats beibehalten.
  2. Verarbeiten Sie sie in eine Datenbank, die eine gute Speichereffizienz hat. Wenn die Dateien ein festes und strenges Format haben (z. B. Spalte X ist immer ein String, Spalte Y ist immer ein 16-Bit-Integer), dann sind Sie wahrscheinlich gut aufgestellt. Andernfalls könnte eine NoSQL-Datenbank besser sein (siehe Antwort von Stefan).

Dies würde ein überprüfbares (aber möglicherweise langsam zugängliches) Archiv mit geringem Risiko des Datenverlusts und eine schnell zugängliche Datenbank schaffen, die sich nicht um den Verlust der Quelldaten kümmern muss, da Sie sie immer von dem Archiv in die Datenbank zurücklesen können.

Sie sollten in der Lage sein, Ihren Speicherplatz zu reduzieren und sollten nicht so viel Speicherplatz benötigen, wie Sie angeben.

Die Indizierung wird der schwierige Teil sein; Sie sollten eine gute Vorstellung davon haben, welchen Teil der Daten Sie effizient abfragen müssen.

3voto

Stefan Kendall Punkte 63658

Eines dieser NoSQL-DBs könnte funktionieren. Ich bezweifle jedoch stark, dass alle so konfigurierbar sind, dass sie auf flachen, begrenzten Dateien sitzen können. Vielleicht sollten Sie sich eines der Open-Source-Projekte ansehen und Ihre eigene Datenbankebene schreiben.

2voto

user406211 Punkte 21

Skalierbarkeit beginnt an einem Punkt jenseits von tabellengetrennten ASCII.

Sei einfach praktisch - akademisiere es nicht - Konvention befreit nicht nur deine Finger, sondern auch deinen Verstand.

1voto

Rob Punkte 5405

Sie können dies mit LINQ-to-Objects tun, wenn Sie sich in einer .NET-Umgebung befinden. Streaming/verzögerte Ausführung, funktionales Programmiermodell und alle SQL-Operatoren. Die Joins funktionieren in einem Streaming-Modell, aber eine Tabelle wird hereingezogen, sodass Sie eine Situation haben müssen, in der eine große Tabelle mit einer kleineren Tabelle verbunden ist.

Die Leichtigkeit beim Formen der Daten und die Möglichkeit, Ihre eigenen Ausdrücke zu schreiben, würden sich wirklich in einer wissenschaftlichen Anwendung zeigen.

LINQ gegen eine durch Trennzeichen getrennte Textdatei ist eine häufige Demonstration von LINQ. Sie müssen die Fähigkeit bereitstellen, LINQ ein tabellares Modell zuzuführen. Suchen Sie nach LINQ für Textdateien für einige Beispiele (z. B. siehe http://www.codeproject.com/KB/linq/Linq2CSV.aspx, http://www.thereforesystems.com/tutorial-reading-a-text-file-using-linq/, etc.).

Erwarten Sie eine Einarbeitungszeit, aber es ist eine gute Lösung für Ihr Problem. Eine der besten Behandlungen zu diesem Thema ist Jon Skeets C# in Depth. Holen Sie sich die "MEAP"-Version von Manning für den frühzeitigen Zugriff auf seine neueste Ausgabe.

Ich habe schon ähnliche Arbeiten mit großen Mailinglisten durchgeführt, die bereinigt, dedupliziert und erweitert werden müssen. Sie sind unausweichlich I/O-gebunden. Probieren Sie Solid State Drives aus, insbesondere Intels "E"-Serie, die eine sehr schnelle Schreibleistung aufweist, und rüsten Sie sie so parallel wie möglich zu. Wir haben auch Grids verwendet, mussten aber die Algorithmen anpassen, um mehrstufige Ansätze zu verwenden, die die Daten reduzieren würden.

Hinweis: Ich stimme den anderen Antworten zu, die betonen, dass das Laden in eine Datenbank und Indizieren sinnvoll ist, wenn die Daten sehr regelmäßig sind. In diesem Fall führen Sie im Wesentlichen ETL aus, was ein in der Lagerhaltungsgemeinschaft gut verstandenes Problem ist. Wenn die Daten jedoch ad hoc sind, haben Sie Wissenschaftler, die ihre Ergebnisse einfach in ein Verzeichnis ablegen, Sie haben einen Bedarf an "agilen/just-in-time"-Transformationen, und wenn die meisten Transformationen Einzelvorgänge von select ... where ... join sind, gehen Sie es richtig an.

1voto

SargeATM Punkte 592

Ich würde Jasons Empfehlung hochwerten, wenn ich den Ruf hätte. Mein einziger Zusatz ist, dass wenn Sie es nicht in einem anderen Format wie der von Jason vorgeschlagenen Datenbank speichern, trägt jede Operation die Parsing-Kosten, anstatt nur einmal, wenn Sie es ursprünglich verarbeiten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X