Hintergrund
Eine lokale Datenbank enthält fast 1,3 Milliarden eindeutige Zeilen. Jede Zeile ist indirekt einem bestimmten Breiten- und Längengrad (Ort) zugeordnet. Jede Zeile hat einen Datumsstempel.
Anwendungsfall
Das Problem ist wie folgt:
- Der Benutzer legt ein Start- / Enddatum und einen Wertebereich fest (z. B. 100 bis 105).
- Das System sammelt alle Zeilen, die dem angegebenen Datum entsprechen, gruppiert nach Standort.
- Das System ermittelt die Orte, an denen während dieser Daten eine statistische Wahrscheinlichkeit besteht, in den angegebenen Wertebereich zu fallen.
- Das System zeigt dem Benutzer alle übereinstimmenden Positionen an.
Dies ist ein Problem der Geschwindigkeit und des Maßstabs.
Frage
Was ist die kostengünstigste Lösungsarchitektur, die Sie sich vorstellen können, mit der ein solches System in weniger als fünf Sekunden Ergebnisse für Benutzer abrufen kann?
Aktuelles System
Die Umgebung ist derzeit:
- PostgreSQL 8.4 (Upgrade ist möglich; Datenbankwechsel ist keine Option)
- R und PL / R.
- XFS
- WD VelociRaptor
- 8 GB RAM (Corsair G.Skill; 1,3 GHz)
- Quad Core GenuineIntel 7 (2,8 GHz)
- Ubuntu 10.10
Hardware-Upgrades sind akzeptabel.
Update - Datenbankstruktur
Die Milliarden von Zeilen befinden sich in einer Tabelle, die ähnelt:
id | taken | location_id | category | value1 | value2 | value3
- id - Primärschlüssel
- genommen - Datum, das der Zeile zugewiesen wurde
- location_id - Verweis auf den Breiten- / Längengrad
- Kategorie - Eine Beschreibung der Daten
- value1 .. 3 - Die anderen Werte, die der Benutzer abfragen kann
Die taken
Spalte enthält in der Regel aufeinanderfolgende Daten pro location_id
Tag. Manchmal enthält jeder Standort Daten von 1800 bis 2010 (etwa 77.000 Daten, von denen viele dupliziert wurden, da jeder Standort Daten im gleichen Datumsbereich enthält).
Es gibt sieben Kategorien und die Tabellen sind bereits nach Kategorien unterteilt (unter Verwendung von untergeordneten Tabellen). Jede Kategorie enthält ~ 190 Millionen Zeilen. In naher Zukunft wird die Anzahl der Zeilen pro Kategorie eine Milliarde überschreiten.
Es gibt ungefähr 20.000 Standorte und 70.000 Städte. Die Standorte sind nach Längen- und Breitengrad mit der Stadt korreliert. Das Zuweisen jedes Standorts zu einer bestimmten Stadt bedeutet, die Stadtgrenzen zu finden, was keine triviale Aufgabe ist.
Ideen
Einige Ideen, die ich habe, sind:
- Suchen Sie einen Cloud-Dienst zum Hosten der Datenbank.
- Erstellen Sie einen SSD-Raid-Streifen (großartiges Video).
- Erstellen Sie eine Tabelle, in der alle Standorte nach Städten zusammengefasst sind (Vorberechnung).
Vielen Dank!
quelle
location_id
eingeography
odergeometry
oder bezieht sich auf eine zweite Tabelle? Ist dielocation_id
Spalte indiziert?Antworten:
Das Wichtigste ist, absolut sicher zu sein, wo der Engpass jetzt für eine bestimmte Anzahl repräsentativer Anforderungen liegt, da Sie nicht zwischen Datenbanken wechseln können.
Wenn Sie vollständige Tabellenscans durchführen, benötigen Sie entsprechende Indizes.
Wenn Sie auf E / A warten, benötigen Sie mehr Speicher für das Caching (Jeff Atwood erwähnte kürzlich, dass 24-Gbit-Systeme auf Desktop-Systemen erreichbar waren).
Wenn Sie auf CPU warten, müssen Sie sehen, ob Ihre Berechnungen optimiert werden können.
Dies erfordert einen spitzen DBA-Hut und einen Betriebssystem-Hut, aber es lohnt sich, um sicherzustellen, dass Sie den richtigen Baum bellen.
quelle
Wie wäre es, wenn Sie die Tabelle basierend auf dem Datumsstempel in mehrere Teile auf verschiedenen Hosts aufteilen? Dies ist horizontal skalierbar. Solange Sie über genügend Boxen verfügen, können Sie eine kleine Aggregations-Engine über diese Setups schreiben.
Wenn Sie feststellen, dass sich der Datumsstempel zu stark ändert, können Sie anhand der Positionen partitionieren - wiederum horizontal skalierbar. (Hoffentlich fügen sie nicht mehr viele Breiten- / Längengrade hinzu!)
quelle
Im schlimmsten Fall deckt der Datumsbereich alle Daten in Ihrer Datenbank ab.
Sie möchten 1,3 Milliarden Datensätze lesen und in weniger als 5 Sekunden eine Analyse für jeden Datensatz im Vergleich zu den eingegebenen Werten auf einer physischen Maschine durchführen. Das Ergebnis können alle oder keine Standorte sein - Sie wissen nichts im Voraus.
Angesichts dieser Parameter würde ich sagen, wahrscheinlich unmöglich.
Schauen Sie sich nur Ihre Festplatte an: Die maximale Dauerfrequenz beträgt weniger als 150 MB / s. Das Lesen von 1,3 Milliarden Datensätzen dauert mehr als 5 Sekunden. In Bezug auf die CPU können Sie in 5 Sekunden keine statistischen Analysen für 1,3 Milliarden Datensätze durchführen.
Ihre einzige Hoffnung (tm :-)) findet eine Art Lookup - Funktion basierend auf den Werten vom Benutzer eingegeben , die die (von einigen Größenordnungen) suchen nach unten werden verengen. Sie können diese Suchfunktion offline berechnen. Ohne mehr über die genauen Übereinstimmungskriterien zu wissen, kann Ihnen wohl niemand sagen, wie das geht, aber ein Beispiel wäre, den Wertebereich in ein diskretes Intervall zu unterteilen und eine Suche zu erstellen, die Ihnen alle Datensätze in diesem Intervall liefert. Solange das Intervall klein genug ist, können Sie echte Arbeit darin leisten, z. B. Einträge entfernen, die nicht mit dem vom Benutzer eingegebenen Wert übereinstimmen. Grundsätzlich Raum gegen Zeit tauschen.
Es kann möglich sein, alle Datensätze (oder zumindest den wichtigen Teil) im Speicher zu behalten. Wahrscheinlich nicht in 8 GB. Dadurch wird zumindest der Festplatten-E / A-Teil eliminiert, obwohl selbst die Speicherbandbreite möglicherweise nicht ausreicht, um alles in 5 Sekunden zu durchsuchen. In jedem Fall ist dies eine andere Technik, um diese Art von Anwendungen zu beschleunigen (in Kombination mit meinem vorherigen Vorschlag).
Sie erwähnen die Verwendung eines Cloud-Dienstes. Ja, wenn Sie für genügend CPU- und E / A-Muskeln bezahlen und Ihre Datenbank auf viele Server verteilen, können Sie sie brutal erzwingen / teilen und erobern.
quelle
Ich bin der zweite Kommentar von rwong zu der Frage: PostgreSQL bietet geeignete Indextypen und -tools (GIST-Indizes, GIN-Indizes, Postgis, geometrische Typen) so an, dass Geodaten und datetime-bezogene Daten entlang dieser Kriterien ohne große Probleme durchsucht werden können.
Wenn Ihre Abfragen zu diesen Kriterien Sekunden dauern, bedeutet dies wahrscheinlich, dass keine solchen Indizes verwendet werden. Können Sie bestätigen, dass Sie diese gegebenenfalls untersucht haben?
quelle
Wenn Sie PostgreSQL- und Breiten- / Längengraddaten verwenden, sollten Sie auf jeden Fall auch PostGIS verwenden. Auf diese Weise können Sie Ihrer Datenbank einen räumlichen GiST-Index hinzufügen, um die Arbeit zu beschleunigen.
Ich habe eine solche Tabelle (mit 350.000 Zeilen) mit einer Konfiguration, die viel kleiner ist als Ihre (2 Core und kaum 2 GB RAM), aber die Suche dauert weniger als eine Sekunde.
quelle
Vielleicht könnten Sie ein relationales Modell brechen, wie es Essbase mit seiner OLAP-Architektur getan hat: Essbase Wikipedia
Was ich meine, ist eine Tabelle pro Stadt zu erstellen, was zu mehr als 1000 Tabellen führt. Nicht ein Tisch, wie Sie vorgeschlagen haben, sondern viele. Indizieren Sie jede Tabelle nach Datum und Ort. Viele Tabellen, viele Indizes -> schneller.
quelle
Sind Sie bei Ihrer Idee, einen Cloud-Dienst zum Hosten der Datenbank zu finden, bereits auf SimpleGeo gestoßen ? Sie haben nur das Menüband eines Speicherdienstes durchtrennt, der anscheinend "speziell darauf abgestimmt ist, Standortdaten wirklich, wirklich schnell zu speichern und abzufragen" - obwohl die Kosten für das Speichern und Abfragen von mehr als einer Milliarde Zeilen diesen Ansatz möglicherweise nicht durchführbar machen.
quelle
Sie erwarten, dass ein Fahrrad auf der Autobahn fährt. Derzeit suchen Sie nach einer Lösung, um nur dieses Problem anzugehen. Sie sehen das Problem nicht voraus. Was ist, wenn Sie 2 Milliarden Datensätze haben? Skalierbarkeit muss angesprochen werden. Antwort ist einfach Objektdatenbanken verwenden. zB Intersystems Cache
und glauben Sie mir, ich bin nicht von Intersystemen ;-)
quelle