Speichern von Zeitreihendaten, relational oder nicht?


184

Ich erstelle ein System, das Geräte mit (wahrscheinlich) 5-Minuten-Intervallen mithilfe von SNMP nach Daten zu unterschiedlichen Metriken wie CPU-Auslastung, Festplattenauslastung, Temperatur usw. abfragt. Das ultimative Ziel besteht darin, einem Benutzer des Systems Visualisierungen in Form von Zeitreihendiagrammen bereitzustellen.

Ich habe in der Vergangenheit die Verwendung von RRDTool in Betracht gezogen, es jedoch abgelehnt, da das unbegrenzte Speichern der erfassten Daten für mein Projekt wichtig ist. Ich möchte einen höheren und flexibleren Zugriff auf die erfassten Daten. Meine Frage lautet also wirklich:

Was ist besser, eine relationale Datenbank (wie MySQL oder PostgreSQL) oder eine nicht relationale oder NoSQL-Datenbank (wie MongoDB oder Redis) in Bezug auf die Leistung bei der Abfrage von Daten für die grafische Darstellung.

Relational

Bei einer relationalen Datenbank würde ich eine data_instancesTabelle verwenden, in der jede Instanz von Daten gespeichert wird, die für jede Metrik erfasst wurden, die für alle Geräte gemessen wird, mit den folgenden Feldern:

Felder: id fk_to_device fk_to_metric metric_value timestamp

Wenn ich ein Diagramm für eine bestimmte Metrik auf einem bestimmten Gerät zeichnen möchte, muss ich diese einzelne Tabelle abfragen , um die anderen Geräte und die anderen für dieses Gerät analysierten Metriken herauszufiltern :

SELECT metric_value, timestamp FROM data_instances
    WHERE fk_to_device=1 AND fk_to_metric=2

Die Anzahl der Zeilen in dieser Tabelle wäre:

d * m_d * f * t

wobei ddie Anzahl von IS - Geräte , m_dist die akkumulative Zahl der Messwerte für alle Geräte aufgezeichnet werden, fist die Frequenz , mit der Daten für die abgefragt wird , und tist die Gesamtmenge an Zeit , das System das Sammeln von Daten ist.

Für einen Benutzer, der ein Jahr lang alle 5 Minuten 10 Metriken für 3 Geräte aufzeichnet , hätten wir knapp 5 Millionen Datensätze.

Indizes

Ohne Indexe fk_to_deviceund fk_to_metricScannen würde diese ständig wachsende Tabelle zu viel Zeit in Anspruch nehmen. Daher ist die Indizierung der oben genannten Felder und auch timestamp(zum Erstellen von Diagrammen mit lokalisierten Zeiträumen) eine Voraussetzung.

Nicht relational (NoSQL)

MongoDB hat das Konzept einer Sammlung , im Gegensatz zu Tabellen können diese ohne Setup programmgesteuert erstellt werden. Mit diesen konnte ich die Speicherung von Daten für jedes Gerät oder sogar jede für jedes Gerät aufgezeichnete Metrik partitionieren.

Ich habe keine Erfahrung mit NoSQL und weiß nicht, ob sie Funktionen zur Verbesserung der Abfrageleistung wie die Indizierung bieten. Im vorherigen Absatz wird jedoch vorgeschlagen, den größten Teil der traditionellen relationalen Abfragearbeit in der Struktur auszuführen, in der die Daten unter NoSQL gespeichert werden.

Unentschieden

Würde sich eine relationale Lösung mit korrekter Indizierung innerhalb eines Jahres auf einen Crawl reduzieren? Oder bietet die sammlungsbasierte Struktur von NoSQL-Ansätzen (die meinem mentalen Modell der gespeicherten Daten entspricht) einen spürbaren Vorteil?


1
Sehr berechtigte Frage, ich selbst habe darüber nachgedacht, ob die relationale Datenbank der richtige Weg ist, um eine Datenstruktur zu speichern, die tatsächlich hierarchisch ist (SNMP-Struktur). Manchmal, wenn ich eine Abfrage schreibe, um selbst triviale Daten abzurufen, ist die Abfrage zu kompliziert. Ich hatte das Gefühl, dass die Daten in eine Form zerlegt werden müssen, die nicht ihre eigene ist. Zum Beispiel ist das Abgleichen von ifnames und ihren Indizes angeblich eine triviale Aufgabe, da beide Kinder derselben übergeordneten OID sind. Die Art und Weise, wie es in der relationalen Datenbank gespeichert wird, bezieht sich jedoch nicht auf die ursprüngliche Struktur, und ich halte es für effizienter, es hierarchisch zu speichern.
Benny

"Für einen Benutzer, der ein Jahr lang alle 5 Minuten 10 Metriken für 3 Geräte aufzeichnet, hätten wir knapp 5 Millionen Datensätze." Ist 10 * 3 * 365 * 24 * 12 nicht ungefähr gleich 3 Millionen, was nicht knapp 5 Millionen ist?
Mathieu Borderé

Antworten:


152

Auf jeden Fall relational. Unbegrenzte Flexibilität und Erweiterung.

Zwei Korrekturen, sowohl im Konzept als auch in der Anwendung, gefolgt von einer Erhöhung.

Korrektur

  1. Es geht nicht darum, "nicht benötigte Daten herauszufiltern"; Es werden nur die benötigten Daten ausgewählt. Ja, wenn Sie einen Index zur Unterstützung der in der WHERE-Klausel angegebenen Spalten haben, ist dieser natürlich sehr schnell und die Abfrage hängt nicht von der Größe der Tabelle ab (das Abrufen von 1.000 Zeilen aus einer 16-Milliarden-Zeilentabelle erfolgt sofort). .

  2. Ihr Tisch hat ein ernstes Hindernis. In Anbetracht Ihrer Beschreibung lautet die tatsächliche PK (Gerät, Metrik, DateTime). (Bitte nennen Sie es nicht TimeStamp, das bedeutet etwas anderes, aber das ist ein kleines Problem.) Die Eindeutigkeit der Zeile wird identifiziert durch:

       (Device, Metric, DateTime)
    
    • Die IdSpalte macht nichts, sie ist völlig überflüssig.

      • Eine IdSpalte ist niemals ein Schlüssel (doppelte Zeilen, die in einer relationalen Datenbank verboten sind, müssen auf andere Weise verhindert werden).
      • Die IdSpalte erfordert einen zusätzlichen Index, der offensichtlich die Geschwindigkeit von behindert INSERT/DELETEund den verwendeten Speicherplatz erhöht .

      • Sie können es loswerden. Bitte.

Elevation

  1. Nachdem Sie das Hindernis beseitigt haben, haben Sie es möglicherweise nicht erkannt, aber Ihr Tisch befindet sich in der sechsten Normalform. Sehr hohe Geschwindigkeit mit nur einem Index auf der PK. Lesen Sie zum Verständnis diese Antwort aus der Was ist die sechste Normalform? weiter vorwärts.

    • (Ich habe nur einen Index, nicht drei; auf den Nicht-SQLs benötigen Sie möglicherweise drei Indizes).

    • Ich habe genau die gleiche Tabelle ( Idnatürlich ohne den "Schlüssel"). Ich habe eine zusätzliche Spalte Server. Ich unterstütze mehrere Kunden aus der Ferne.

      (Server, Device, Metric, DateTime)

    Die Tabelle kann verwendet werden, um die Daten mit genau demselben SQL-Code zu schwenken (dh Devicesüber die Oberseite und die Unterseite Metricsoder geschwenkt) (ja, die Zellen wechseln). Ich verwende die Tabelle, um eine unbegrenzte Anzahl von Grafiken und Diagrammen für Kunden bezüglich ihrer Serverleistung zu erstellen.

    • Überwachen des Statistikdatenmodells .
      (Zu groß für Inline; einige Browser können Inline nicht laden; klicken Sie auf den Link. Auch dies ist die veraltete Demoversion. Aus offensichtlichen Gründen kann ich Ihnen kein kommerzielles Produkt DM zeigen.)

    • Es ermöglicht mir, Diagramme wie dieses zu erstellen , sechs Tastenanschläge, nachdem ich mit einem einzigen SELECT-Befehl eine unformatierte Überwachungsstatistikdatei vom Kunden erhalten habe . Beachten Sie das Mix-and-Match; Betriebssystem und Server im selben Diagramm; eine Vielzahl von Pivots. Natürlich gibt es keine Begrenzung für die Anzahl der Statistikmatrizen und damit für die Diagramme. (Wird mit freundlicher Genehmigung des Kunden verwendet.)

    • Leser, die mit dem Standard zur Modellierung relationaler Datenbanken nicht vertraut sind, finden die IDEF1X-Notation möglicherweise hilfreich.

Eine Sache noch

Last but not least ist SQL ein IEC / ISO / ANSI-Standard. Die Freeware ist eigentlich Non-SQL; Es ist betrügerisch, den Begriff SQL zu verwenden, wenn sie den Standard nicht bereitstellen. Sie können "Extras" bereitstellen, aber ihnen fehlen die Grundlagen.


1
@PerformanceDBA Würden Sie das vorgeschlagene Schema für ein Setup verwenden, das ~ 3 Millionen Kennzahlen mit einer Frequenz von 1 Minute verarbeiten muss? Wie würden Sie die PK für einen solchen Tisch bestellen? Würden Device, Metric, DateTime nicht eine Fragmentierung verursachen und das RDBMS zu vielen Seitenaufteilungen zwingen? Wenn DateTime an erster Stelle steht, wird die Fragmentierung verringert (ich gehe davon aus, dass zeitlich geordnete Einfügungen vorliegen), die Lesevorgänge werden jedoch am schlechtesten.
Marcob

1
@ Buchi. Ich benutze Sybase ASE. Dies ist jedoch kein Plattformproblem (sicher, die High-Plattformen bieten eine um Größenordnungen bessere Leistung als das Low-End; drei Größenordnungen besser als Oracle, aber das ist nicht der Punkt), das Aufstellen des Diagramms aus der Tabelle " funktioniert "auf jeder Plattform. Verwenden Sie das richtige Werkzeug für den Job. Das RDBMS ist ein Datenbankwerkzeug, kein Grafiktool. gnuplot, Apple Numbers (oder wenn Sie zehnmal so viel bezahlen möchten, für halb so viel, MS Excel) sind Diagrammwerkzeuge, keine Datenbankwerkzeuge. Heutzutage verwenden wir Schichten von Werkzeugen, um ein Ergebnis zu erzielen. Der Monolith ist ein Dinosaurier.
PerformanceDBA

1
@ Marcob. Ihre Frage ist gut, kann aber in den Kommentaren nicht richtig beantwortet werden. Wenn Sie eine neue Frage öffnen und mir eine E-Mail senden (zum Profil gehen), werde ich sie beantworten. Für die schnelle Antwort hier. (1) ~ 3 Millionen Metriken. Großartig, je mehr desto besser, desto schöner werden die INSERT-Punkte. Ihre würden Konflikte auf der letzten Seite garantieren. Der Server ist multithreaded, ja? Partitionieren Sie die Tabelle. Verwenden Sie FILLFACTOR und lassen Sie Platz für Einfügungen, um Seitenaufteilungen zu vermeiden. (2) ~ 3 Mill zeigt an, dass die Metriken nicht normalisiert sind. Wenn Sie dies korrigieren, ist es noch schneller.
PerformanceDBA

1
@ Marcob. (3) Ich verwende den angegebenen Index genau , um die Einsätze unter Last zu verteilen, was keine Konflikte gewährleistet. (4) Daher erhält meine Methode beide Einfügungen ohne Konflikte und eine hohe Leistung bei SELECTs.
PerformanceDBA

2
@Loic. Warum um alles in der Welt sollte jeder, der eine Investition (Daten; Code) in eine SQL-Plattform hat, die Zeitreihendaten einfach und mit sehr hoher Leistung verarbeitet (wie in der Antwort beschrieben), zu einer TSDB ohne SQL migrieren? unbekannte Geschwindigkeit für etwas anderes als Zeitreihendaten? Warum sollte jemand, der eine Anforderung hat, die nur Zeitreihendaten überschreitet, keine SQL-Plattform verwenden? Der Geist verwirrt. TSDB ist nur in der traurigen Instanz schneller als Relational, wenn die Daten in einer Datenbank gespeichert, aber nicht relational normalisiert sind. Z.B. wenn IdSpalten als "Schlüssel" verwendet werden. Wie von den "Theoretikern" empfohlen.
PerformanceDBA

21

Fand die obigen Antworten sehr interessant. Ich versuche hier ein paar weitere Überlegungen hinzuzufügen.

1) Datenalterung

Das Zeitreihenmanagement muss normalerweise Alterungsrichtlinien erstellen. Ein typisches Szenario (z. B. Überwachung der Server-CPU) erfordert Folgendes:

  • 1-Sekunden- Rohproben für einen kurzen Zeitraum (z. B. für 24 Stunden)

  • 5- minütige Detailaggregatproben für einen mittleren Zeitraum (z. B. 1 Woche)

  • 1 Stunde Detail darüber (zB bis zu 1 Jahr)

Obwohl relationale Modelle es sicher ermöglichen (mein Unternehmen hat massive zentralisierte Datenbanken für einige große Kunden mit Zehntausenden von Datenreihen implementiert), diese angemessen zu verwalten, bietet die neue Generation von Datenspeichern interessante Funktionen, die untersucht werden müssen:

  • automatisierte Datenbereinigung (siehe Befehl EXPIRE von Redis)

  • mehrdimensionale Aggregationen (z. B. Jobs mit Kartenreduzierung a-la-Splunk)

2) Echtzeiterfassung

Noch wichtiger ist, dass einige nicht relationale Datenspeicher von Natur aus verteilt sind und eine wesentlich effizientere Echtzeit- (oder nahezu Echtzeit-) Datenerfassung ermöglichen, die aufgrund der Erstellung von Hotspots (Verwaltung der Indizierung beim Einfügen) ein Problem mit RDBMS darstellen kann eine einzelne Tabelle). Dieses Problem im RDBMS-Bereich wird normalerweise gelöst, indem auf Stapelimportverfahren zurückgegriffen wird (wir haben es in der Vergangenheit auf diese Weise verwaltet), während No-SQL-Technologien eine massive Echtzeiterfassung und -aggregation erfolgreich durchgeführt haben (siehe beispielsweise Splunk, wie in früheren Antworten erwähnt). .


7

Ihre Tabelle enthält Daten in einer einzelnen Tabelle. Relational vs non relational ist also nicht die Frage. Grundsätzlich müssen Sie viele sequentielle Daten lesen. Wenn Sie über genügend RAM verfügen, um Daten im Wert von einem Jahr zu speichern, können Sie Redis / MongoDB usw. nicht mehr verwenden.

In den meisten NoSQL-Datenbanken werden Ihre Daten am selben Speicherort auf der Festplatte und in komprimierter Form gespeichert, um den Zugriff auf mehrere Festplatten zu vermeiden.

NoSQL macht dasselbe wie das Erstellen des Index für die Geräte-ID und die Metrik-ID, jedoch auf seine eigene Weise. Selbst wenn Sie dies in der Datenbank tun, befinden sich der Index und die Daten möglicherweise an verschiedenen Stellen, und es würde eine Menge Festplatten-E / A geben.

Tools wie Splunk verwenden NoSQL-Backends zum Speichern von Zeitreihendaten und verwenden dann Map Reduce, um Aggregate zu erstellen (was möglicherweise später gewünscht wird). Meiner Meinung nach ist die Verwendung von NoSQL eine Option, da die Leute es bereits für ähnliche Anwendungsfälle ausprobiert haben. Aber wird eine Million Zeilen die Datenbank zum Crawlen bringen (möglicherweise nicht, mit anständiger Hardware und richtigen Konfigurationen).


1
Können Sie erklären, wie die Tabelle "de-normalisiert" ist? Marcus hat einen Fehler in der Tabelle, aber es ist kein Normalisierungsfehler.
PerformanceDBA

Ich werde mich korrigieren, Tabellen sind im traditionellen Sinne normalisiert. Ich meinte de-normalisiert in dem Sinne, dass der Anwendungsfall hier alle Daten in einer Tabelle enthält.
Ravindra

4

Erstellen Sie eine Datei und nennen Sie sie 1_2.data. seltsame Idee? Was man bekommt:

  • Sie sparen bis zu 50% des Speicherplatzes, da Sie den Wert fk_to_device und fk_to_metric nicht für jeden Datenpunkt wiederholen müssen.
  • Sie sparen noch mehr Platz, weil Sie keine Indizes benötigen.
  • Speichern Sie Paare von (Zeitstempel, metrischer Wert) in der Datei, indem Sie die Daten anhängen, damit Sie eine Bestellung per Zeitstempel kostenlos erhalten. (vorausgesetzt, Ihre Quellen senden keine Daten für ein Gerät aus der Reihenfolge)

=> Abfragen nach Zeitstempel werden erstaunlich schnell ausgeführt, da Sie mithilfe der binären Suche die richtige Stelle in der Datei finden können, aus der Sie lesen können.

Wenn es Ihnen noch besser gefällt, denken Sie darüber nach, Ihre Dateien so aufzuteilen.

  • 1_2_january2014.data
  • 1_2_february2014.data
  • 1_2_march2014.data

oder benutze kdb + von http://kx.com, weil sie das alles für dich tun :) spaltenorientiert ist das, was dir helfen kann.

Es taucht eine Cloud-basierte spaltenorientierte Lösung auf. Vielleicht möchten Sie einen Blick darauf werfen: http://timeseries.guru


Ich habe einen Blog-Beitrag zum Thema geschrieben. mit Google Übersetzer finden Sie es vielleicht hilfreich: blog.michaelwittig.info/die-spaltenorientierte-datenbank-kdb
hellomichibye

3

Wenn Sie sich GPL-Pakete ansehen, ist RRDTool eine gute Wahl . Es ist ein gutes Werkzeug zum Speichern, Extrahieren und Zeichnen von Zeitreihendaten. Ihr Anwendungsfall sieht genauso aus wie Zeitreihendaten.


2

Dies ist ein Problem, das wir bei ApiAxle lösen mussten. Wir haben einen Blog-Beitrag darüber geschrieben, wie wir es mit Redis gemacht haben. Es ist noch nicht lange da draußen, aber es erweist sich als effektiv.

Ich habe RRDTool auch für ein anderes Projekt verwendet, das ausgezeichnet war.


2

Ich denke, dass sich die Antwort auf diese Art von Frage hauptsächlich auf die Art und Weise beziehen sollte, wie Ihre Datenbank Speicher verwendet. Einige Datenbankserver verwenden RAM und Festplatte, andere nur RAM (optional Festplatte für Persistenz) usw. Die meisten gängigen SQL-Datenbanklösungen verwenden Speicher + Festplattenspeicher und schreiben die Daten in ein zeilenbasiertes Layout (jedes eingefügte Raw wird in dasselbe geschrieben physischer Standort). In Zeitreihenspeichern ist die Arbeitslast in den meisten Fällen wie folgt: Relativ geringes Intervall mit einer großen Anzahl von Einfügungen, während Lesevorgänge spaltenbasiert sind (in den meisten Fällen möchten Sie einen Datenbereich aus einer bestimmten Spalte lesen, die eine Metrik darstellt).

Ich habe festgestellt, dass Columnar Databases (google it, MonetDB, InfoBright, parAccel usw.) hervorragende Arbeit für Zeitreihen leisten.

Was Ihre Frage betrifft, die ich persönlich für etwas ungültig halte (wie alle Diskussionen mit dem Fehlerbegriff NoSQL - IMO): Sie können einen Datenbankserver verwenden, der einerseits SQL sprechen kann, was Ihr Leben sehr einfach macht, da jeder SQL für viele kennt Jahre und diese Sprache wurde immer wieder für Datenabfragen perfektioniert; Verwenden Sie RAM, CPU-Cache und Festplatte jedoch weiterhin spaltenorientiert, damit Ihre Lösung am besten zu Zeitreihen passt


2

5 Millionen Zeilen sind nichts für die heutigen Torrentialdaten. Erwarten Sie, dass die Daten in wenigen Monaten in der TB oder PB vorliegen. Zu diesem Zeitpunkt skalieren RDBMS nicht auf die Aufgabe und wir benötigen die lineare Skalierbarkeit von NoSql-Datenbanken. Die Leistung würde für die zum Speichern der Daten verwendete Spaltenpartition erreicht, indem mehr Spalten und weniger Zeilen hinzugefügt würden, um die Leistung zu steigern. Nutzen Sie die Open TSDB-Arbeit, die über HBASE oder MapR_DB usw. ausgeführt wird.


"RDBMS skalieren nicht auf die Aufgabe" - warum sollten sie nicht? code.facebook.com/posts/190251048047090/…
Zathrus Writer

1

Ich habe regelmäßig ähnliche Anforderungen und verwende seit kurzem Zabbix, um diese Art von Daten zu sammeln und zu speichern. Zabbix verfügt über eine eigene Grafikfunktion, aber es ist einfach genug, die Daten aus der Zabbix-Datenbank zu extrahieren und zu verarbeiten, wie Sie möchten. Wenn Sie Zabbix noch nicht ausgecheckt haben, lohnt es sich möglicherweise, dies zu tun.


Ja, Zabbix ist nett und bereits in die SNMP-Überwachung integriert. Zabbix kann MySQL oder PostgreSQL verwenden und funktioniert unter Ubuntu mehr oder weniger sofort.
Dirk Eddelbuettel

Vielen Dank, ich kenne Zabbix und viele andere SNMP-Tools. Ich entwickle dieses Projekt jedoch als Bildungsprozess in dem hier diskutierten Thema und vielen anderen Aspekten. Ein guter Punkt!
Marcus Whybrow

0

Sie sollten in die Zeitreihendatenbank schauen . Es wurde zu diesem Zweck erstellt.

Eine Zeitreihendatenbank (TSDB) ist ein Softwaresystem, das für die Verarbeitung von Zeitreihendaten, nach Zeit indizierten Zahlenfeldern (Datum / Uhrzeit oder Datum / Uhrzeit) optimiert ist.

Beliebtes Beispiel für die Zeitreihendatenbank InfluxDB


füge
timescaledb
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.