So bearbeiten Sie Anfragen von mehr als 500 Millionen Elementen


8

Die Struktur meiner Daten ist wie folgt:

date: <timestamp>
filter_a: <integer> -> range [0, 1000]
filter_b: <integer> -> range [0, 1000]
filter_c: <integer> -> range [0, 86400]
filter_d: <integer> -> range [0, 6]
group: <string>
second_group: <integer>
variable_a: <float>
variable_b: <float>
variable_c: <float>
a couple more no very important

Ich muss die folgenden Abfragen durchführen:

Zuerst:

  • Filtern von Daten durch date, filter_a, filter_b, filter_cund andere

Zweitens mit den gefilterten Daten:

  • Zähle alle Datensätze
  • erhalten Durchschnitt von variable_a, variable_bundvariable_c
  • bekommen Standardabweichung von variable_a, variable_bundvariable_c
  • Holen Sie sich Quartile von variable_a, variable_bundvariable_c
  • Gruppendaten nach groupoder second_groupund aggregieren (Count, Avg, Std, ..)

Die Zahl der Benutzer des Systems ist etwa 10 oder 15, aber die Anzahl der Elemente ist sehr groß, gerade jetzt ist es 70M aber es wird 500M in ein paar Wochen , und es wird 1000M in etwa ein Jahr.

Die Anzahl der Abfragen ist gering, nicht mehr als 10 Benutzer gleichzeitig. Mein Problem ist, wie diese Abfragen mit dieser riesigen Datenmenge behandelt werden.

Was habe ich bisher versucht?

  • Ich begann mit mongodb, am Anfang war es schnell, aber es wurde langsam, wenn Quartile mit 10M + berechnet wurden. Es hat sich verbessert, als ich Indizes hinzugefügt habe, aber es hat nicht viel geholfen, als ich alle Daten abfragen musste. Ich habe angefangen, Mongodb zu verwenden, weil die Daten sehr dynamisch waren, aber zum Glück wird sich das Datenformat "nicht mehr ändern".

  • Da filter_aund filter_bwie Knoten gesehen werden konnte, habe ich es versucht neo4j. Ich mochte es neo4j sehr, aber mein Diagramm hatte viele Kanten, so dass Abfragen nicht sehr schnell waren.

  • Da sich das Datenformat nicht ändert und es sich nur um eine Sammlung / Tabelle handelt und daher keine Verknüpfungen in SQL erforderlich sind, habe ich postgresql überprüft. Meine Tests mit postgresql waren schneller, aber ich fürchte, es könnte in Zukunft nicht richtig skaliert werden.

Was brauche ich?

  • Ist postgresql eine gute Wahl für diesen Fall?
  • Gibt es eine andere Art von Datenbank, die ich verwenden könnte? Welches ist das beste für diesen Fall?
  • Was könnte ich noch tun, um es zu verbessern?

Bearbeiten

  • Täglich werden etwa 1 Million Elemente eingefügt, die sich im Laufe der Zeit nicht ändern sollten.
  • Die Schreibgeschwindigkeit ist nicht wichtig
  • Die schwierige Anforderung besteht darin, schnell zu lesen / zu aggregieren

Vielen Dank!


1
Wie wäre es mit indizierten Ansichten in SQL Server / metastasierten Ansichten in Oracle? Dies ist ein laufendes Aggregat der Basistabelle. Wenn die Basistabelle geändert wird, wird der Index auch im laufenden Betrieb geändert. Dann können Sie immer Aggregate abfragen, die bereits für Sie berechnet wurden.
Ali Razeghi

@AliRazeghi indizierte Ansichten ist eine gute Idee. Wie auch immer, zuerst möchte ich die beste Datenbank / das beste Design auswählen, bevor ich die Abfragen selbst optimiere
Andres

1
Um nur in Postgres zu optimieren, möchte ich sagen, dass BRIN-Indizes hier helfen könnten, aber ich habe nichts anderes getan, als darüber zu lesen. postgresql.org/docs/9.5/static/brin-intro.html
Erik Darling

1
Persönlich habe ich eine Datenbank mit mehreren Milliarden Zeilenberichten auf einem OLTP-Server ohne viel Speicher geerbt. Glücklicherweise waren die am häufigsten abgefragten Teile davon die letzten 3 Wochen, aber Tischscans waren keine Seltenheit. Ehrlich gesagt haben wir durch die Verwendung einer sehr guten Komprimierung, Partitionierung, Partitionseliminierung, Partitionierungsschema, SAN-Cache-Optimierung und Entfernen nicht verwendeter Indizes eine sehr gute Leistung unter MS SQL 2008 Ent erzielt. 1 Milliarde wird für PGSQL nicht zu schwer sein. Wie breit ist jede Zeile oder wie viel Platz wird Ihrer Meinung nach in jeder Zeile benötigt, und wie viele Indizes werden pro Tabelle oder Eingabeprozess vorhanden sein?
Ali Razeghi

2
@Andres gut, das hängt davon ab, in welcher DB-Engine sie sich befindet und wie groß die maximale Größe jeder Zeile ist, damit wir sie berechnen können. Zum Beispiel hat PostgreSQL varchar und nur char, char ist einfach zu berechnen, varchar müssten wir die durchschnittliche Länge erraten. Wenn wir wissen könnten, um welche Feldtypen es sich handelt (es sei denn, es ist Mongo oder etwas, das es in einem Dokument mit einem eigenen Format speichert), ungefähr wie viele Zeichen wir in jedem Dokument erwarten und wie viele Indizes mit den Spalten. 8 GB RAM scheinen zu niedrig zu sein, um sie effizient aus dem Speicher zu ziehen, insbesondere wenn dieser RAM mit anderen Tabellen und Ressourcen auf dem Server geteilt wird.
Ali Razeghi

Antworten:


5

Anstatt sich auf eine relationale Datenbank zu stützen, um diese statistischen Berechnungen für Zeitreihendaten durchzuführen, würde ich vorschlagen, dass Sie diese mathematischen und Nachbearbeitungsarbeiten außerhalb der Datenbank in eine Clientanwendung verschieben.

Mit einer Skriptsprache wie Python oder Ruby können Sie das Problem schrittweise lösen, indem Sie über einen Zeitraum mit fester Breite nach "Datenblöcken" abfragen, eine statistische Zwischenzusammenfassung berechnen und die Ergebnisse während der Schleife über mehrere Blöcke hinweg kombinieren über die ganze Geschichte. Einige statistische Kennzahlen lassen sich nur schwer über mehrere Blöcke hinweg kombinieren, aber so etwas wie Avg () benötigt nur sum () und count () pro Block, O (1) vs. O (Blockgröße), sodass das Zusammenführen von Blöcken gut skaliert werden kann.


Ich habe so etwas mit Python / Pandas versucht . Der Kalkül war schneller (ein paar Sekunden), aber das Abrufen aller Daten war langsam. Vielleicht könnte ein besserer chunksizehelfen. +1
Andres

1

Da sich Ihre Daten nicht ändern und nur angehängt werden, würde ich die Daten speichern, wo immer Sie möchten. Amazon S3 zum Beispiel, aber jede schnell lesende Datenbank ist in Ordnung. Keine Indizes. Die von Ihnen ausgewählte Datenbank / FS sollte die Option haben, die Daten in Buckets zu lesen: Sie könnten beispielsweise eine Datei pro Tag mit Ihren 1M-Datensätzen haben.

Dann würde ich Spark verwenden, um die Filterung / Analyse durchzuführen. Es ist clusterbasiert und kann auf Ihre Bedürfnisse skaliert werden.


Ich stimme zu, ich habe meinen Datensatz bereits pro Tag getrennt. Ich dachte auch an HDFS und HBase
Andres

0

Die Reaktion hängt davon ab, wie Sie die Daten danach verwenden. Wenn für die Verarbeitung besser Cassandra verwenden, wenn für die Analyse besser Hive verwenden.


Ich verstand, dass Bienenstock nicht die beste Wahl sein konnte real time. Liege ich falsch?
Andres

1
Ja, HBase dient zum Lesen / Schreiben in Echtzeit. Aber Cassandra kann das auch. Aber ich denke HBase ist besser.
Artemy Prototyping

0

Diese Art von Situation ist ideal für Data Warehousing mit den von Ralph Kimball und Co. perfektionierten Techniken auf Plattformen wie SQL Server (die mir am besten vertraute). Sie wurden speziell für diese Art von Szenario entwickelt: riesige Mengen von Datensätzen mit relativ statischen Daten, für die Sie Aggregate dieser Art berechnen müssen. NeinDie relationale Technik passt zu ordnungsgemäß implementiertem Data Warehousing in Anwendungen dieser Art, obwohl einige sicherlich besser sind als andere, wenn sich Ihr Unternehmen die Lizenzen für die Softwarepakete (wie SQL Server Analysis Services), die sie implementieren, einfach nicht leisten kann. Es gibt auch eine Lernkurve für die Implementierung von Sprachen wie MDX, die auf diese Art des Datenzugriffs zugeschnitten sind. Wenn Data Warehousing eine praktikable Option für Ihr Unternehmen ist, verschwenden Sie keine Zeit mit der Suche nach einer relationalen Lösung. Dies ist kein relationales Datenbankproblem. Ich kann bei Bedarf einige grundlegende Verweise auf Kimball usw. und Links zu SSAS und MDX (leider kann ich nicht mit Oracle und anderen Konkurrenten, mit denen ich nicht vertraut bin) veröffentlichen. Ich hoffe das hilft.

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.