Speichern großer Datenmengen von einem Sensorarray

14

Ich wurde beauftragt, eine Lösung (App und DB) zu implementieren, um die Datenproben von einem riesigen Sensorarray zu speichern. Das Array besteht derzeit aus ungefähr 20.000 Sensoren, aber das wird bald auf 100.000 Sensoren anwachsen. Jeder Sensor sendet alle 10 Sekunden ein Datenmuster und jedes Muster ist 28 Byte groß.

Das Betragen führt also zu:

  • 8640 Proben pro Sensor und Tag
  • 242 KB Daten pro Sensor und Tag
  • 864 Millionen Proben pro Tag

Jetzt habe ich mich gefragt, wie ich die Daten am besten speichern / abrufen kann. Ich bin diesem Projekt "beigetreten", nachdem die Software bereits angegeben wurde, sodass sie unter Verwendung von SQL Server auf einer Windows-Plattform implementiert werden muss.

Die aktuelle Lösung in meinem Kopf besteht darin, eine Datenbank mit zwei Tabellen zum Speichern der Datenbeispiele zu erstellen. Das erste dient als eine Art Index für das zweite, in dem die gesammelten Stichproben pro Tag und Sensor in einem Binärfeld gespeichert werden:

Table 1:

  RecordID - BigInt - Identity
  SensorID - BigInt - Primary Key
  Date - DateTime - Primary Key (yyyy-mm-dd)

Table 2:

  RecordID - BigInt - Primary Key (from an insert into Table 1)
  Data - Binary 

Grundsätzlich schreibe ich die Samples aller Sensoren in temporäre Dateien (1 pro Sensor). Am Ende eines jeden Tages werde ich dann einen Eintrag in Tabelle 1 erstellen, die generierte RecordID verwenden und die Datei in das Datenfeld in Tabelle 2 sichern.

Auf diese Weise habe ich nur 100.000 Einträge pro Tag in der Tabelle, anstatt 864 Millionen Einträge. Die Daten sollten im LAN oder im Hochgeschwindigkeits-WAN verfügbar sein, sodass das Abrufen der Sensordaten auf Tagesbasis akzeptabel wäre.

Obwohl alle Daten gespeichert werden müssen, werden die meisten wahrscheinlich nie gelesen. Die Anzahl der Lesevorgänge in der Tabelle (n) wird also nicht größer sein als die Anzahl der Schreibvorgänge.

Ich weiß, dass ich etwas mithilfe des Dateisystems implementieren könnte, indem ich nur den Pfad zu den Datendateien speichere, aber ich habe gelesen, dass SQL Server NTFS übertrifft, während Ihre Binärfelder dank 256 KB weniger sind. (Ein grauer Bereich liegt zwischen 256 KB und 1 MB, während NTFS SQL Server für Binärgrößen> 1 MB bei weitem übertrifft.)

Ich bin auch etwas vorsichtig, wenn ich Daten von 100.000 Sensoren ohne Probleme im Dateisystem in eigenen Dateien speichern möchte, indem ich entweder große Mengen von Dateien in einem Ordner oder eine komplexe Baumstruktur mit wenigen Dateien in jedem Ordner habe, ohne dies zu tun sogar unter Berücksichtigung der Dateifragmentierung.

  1. Kann mir jemand praktische Ratschläge / Kommentare zu den oben genannten Themen geben?

  2. Gibt es offensichtliche Fallstricke, in die ich fallen werde?

  3. Die Beispieldaten werden recht gut komprimiert. Eine 242-kB-Datei wird auf ca. 85 kB komprimiert. Kann ich jedoch eine Art von Komprimierung auf Datenbankebene implementieren, sodass die Beispieldaten (Spalte) automatisch komprimiert werden?

  4. Ist SQL Server eine offensichtlich falsche Wahl für dieses Projekt?

  5. Ist mein Design der beiden Tische sinnvoll, oder könnte ich es genauso gut zu einem einzigen Tisch kombinieren, der immer noch so "performant" ist wie die beiden Tische?

Oliver
quelle
5
SQL Server unterstützt in solchen Fällen die Komprimierung auf Zeilen- und Tabellenebene.
JNK
2
Benötigen Sie Table1, da nur 1 Eintrag / Sensor / Tag vorhanden ist?
GalacticJello
2
Was planen Sie mit diesen Daten zu tun, sobald sie in der Datenbank sind? Ich kann mir nicht vorstellen, Sensordaten in einem Binärformat zu aggregieren, zumindest nicht einfach oder schnell auf diesen Ebenen.
Datum
1
100.000 Sensoren x 10 Abtastungen pro Sekunde x 28 Byte pro Abtastung x 24 Stunden pro Tag = 2,2 TB pro Tag. Das ist viel in zwei Tabellen zu setzen.
Datum
2
@AlexKuznetsov: Ich habe mich über die SQL Server-Auswahl gewundert, aber sie sind Microsoft-Gold-Partner. Ich denke, das ist der Hauptgrund.
Oliver

Antworten:

12

Ja, es gibt eine ziemlich große Gefahr, auf die Sie ziemlich schnell stoßen werden, und das hängt mit der Größe und Wartung der Tische zusammen. Sie sind auf dem richtigen Weg, wenn Sie sagen, dass Sie Ihre Daten täglich in eine temporäre Tabelle einfügen und dann in Ihre permanente Tabelle verschieben möchten, aber Sie werden bald Probleme mit diesem Schema bekommen.

Angenommen, Sie möchten die Datenmenge des ältesten Monats nach zwei Jahren "rollen". In Ihrem Entwurf müssten Sie eine DELETE-Anweisung für Ihren großen, großen Tisch ausgeben. Dies wird wahrscheinlich etwas langsam sein, abhängig von der Anzahl der Indizes, die Sie haben. Außerdem wird eine Indexfragmentierung verursacht, und die einzige Möglichkeit, dies zu beheben, besteht darin, die Indizes für diese sehr große Tabelle neu zu erstellen oder zu organisieren, was ebenfalls zu Leistungsproblemen führen würde. Es gibt eine ganze Reihe weiterer Probleme, die sich auch mit dem Design eines großen Einzeltisches befassen. Zum Beispiel können Sie mit einer großen, einzelnen Tabelle keine FILEGROUP- basierten Sicherungen durchführen. Wenn Sie also eine vollständige Sicherung Ihrer Datenbank durchführen möchten, wird dies GROSS und die Fertigstellung dauert LANG .

Was ist die Lösung? Tabellenpartitionierung. Lesen Sie dies an so vielen Orten wie möglich. Grundsätzlich können Sie bei der Partitionierung Ihre Daten auf "Tabellen in Tabellen" aufteilen. Jede Partition hat dasselbe Schema und wird über das Tabellenobjekt aufgerufen, kann jedoch unterschiedlich indiziert und verwaltet werden. Partitionen sind im Grunde Tabellen, die von einem nützlichen Schlüssel getrennt werden. In Ihrem Fall wird es wahrscheinlich Datum sein. Sie können genau wie (und genauso schnell wie) Tabellen gelöscht werden. Wenn Sie also Ihre Big-Data-Tabellen nach Datum partitionieren, können Sie einfach alte Partitionen sofort löschen, ohne die Indizes der anderen Partitionen zu beeinträchtigen. Sie können Partitionen in verschiedenen Dateigruppen ablegen. Dies bedeutet, dass ältere Partitionen entfernt oder auf einen günstigeren Commodity-Speicher übertragen werden können, wenn dies nicht allgemein verwendet wird. Last but not least können Sie in SQL 2012auf Ihren älteren schreibgeschützten Partitionen , während auf der aktiven Partition, auf der Sie alle Ihre Sensordaten einfügen, ein anderes, stärker einfügeorientiertes Indizierungsschema verwendet wird.

Hoffe das hilft. Sie haben eine Menge Nachforschungen in Bezug auf Partitionierung und Partitionierungsschemata anzustellen, aber hoffentlich wissen Sie jetzt, in welche Richtung Sie schauen müssen.

PS: Oh, und ich habe Ihre Liste mit Fragen mit Aufzählungszeichen vergessen ... Antwort 1, 2 und 5. Siehe oben. Antwort 3: In SQL Server können Sie Partitionen für Partitionen komprimieren. Komprimieren Sie also Ihre älteren Partitionen aggressiv mithilfe der PAGE-Komprimierung. Ich bin jedoch der Meinung, dass Ihre nicht in der Reihe befindlichen großen Datentypen in diesem Fall nicht komprimiert werden. Auch hier möchten Sie möglicherweise dieses Problem beheben, indem Sie Ihre Sensorwerte normalisieren. Antwort 4: Auf keinen Fall, aber wenn Sie statische Daten nur tagsüber speichern und sie nicht auf andere Weise durchsuchen möchten, sind komprimierte Flatfiles möglicherweise ein viel einfacherer Weg.

PPS: Oh, und noch etwas. Sie brauchen keine Zwei-Tabellen-Lösung, damit dies alles funktioniert. Große binäre Sensordaten sollten vom Typ VARBINARY (MAX) sein, da ihre Werte " out of row " gespeichert werden können , aber immer noch eine Spalte in einer einzelnen Tabelle sind (siehe die Dokumentation zu sp_tableoption ). Sie können jedoch erwägen, einige Ihrer Sensordaten aus den in der Tabelle enthaltenen Binärdaten zu normalisieren, da Ihre Datenbank nicht viel besser ist als das Abrufen von Sensordatenblöcken nach Zeit, wenn Sie dies nicht tun.

Dave Markle
quelle
Tolle Infos, danke. Ich bin mir nicht ganz sicher, was Sie in diesem Fall mit "normalisieren" meinen. Ich gehe jedoch davon aus, dass Sie meinen, ich sollte einige der nützlicheren Felder in den Datenblöcken extrahieren und sie in ihren eigenen Spalten speichern. Wenn ja, dann wollte ich das anfangs nicht, weil es bedeutet, dass ich am Ende 864 Millionen Zeilen pro Tag habe. Wenn Sie alles zusammenstellen und in einem Block speichern, sind es nur 100.000 Zeilen pro Tag. Oder gibt es einen besseren Weg?
Oliver
1
Wenn Sie eine Datenbank verwenden, dann ist das genau das, was ich meine. 864 Millionen Zeilen pro Tag können effizient verarbeitet werden, wenn Sie die richtige Hardware, das richtige Indexierungsschema und das richtige Partitionsschema haben, damit dies funktioniert. Es hängt alles davon ab, was Ihre Anforderungen wirklich sind und warum Sie all diese Daten speichern. Wenn es nur zu Archivierungszwecken ist, ist die binäre Spalte in Ordnung. Wenn Sie mithilfe von SQL Server Geschäftswert daraus extrahieren möchten, ist das eine ganz andere Geschichte.
Dave Markle
0

Betrachten Sie eine Hadoop-Lösung. 2 Tb / Tag summieren sich schnell. Denken Sie auch daran, nur Delta-Datensätze, dh einen Anfangswert, und nur dann zu protokollieren, wenn eine Änderung auftritt.

Carter Shore
quelle