Welcher Datenspeicher eignet sich am besten für mein Szenario?

10

Ich arbeite an einer Anwendung, bei der Aktualisierungs- / Auswahlabfragen in der Datenbank sehr häufig ausgeführt werden.

Ich habe eine Basistabelle (A), die ungefähr 500 Datensätze für eine Entität pro Tag enthält. Und für jeden Benutzer im System wird eine Variation dieser Entität basierend auf einigen Einstellungen des Benutzers erstellt und sie werden in einer anderen Tabelle (B) gespeichert. Dies geschieht durch einen Cron-Job, der jeden Tag um Mitternacht ausgeführt wird.

Wenn sich also 10.000 Benutzer und 500 Datensätze in Tabelle A befinden, enthält dieser Tag 5 Millionen Datensätze in Tabelle B. Ich speichere immer Daten für einen Tag in diesen Tabellen und archiviere um Mitternacht historische Daten in HBase. Dieses Setup funktioniert einwandfrei und ich habe bisher keine Leistungsprobleme.

In letzter Zeit haben sich die Geschäftsanforderungen geändert, und jetzt ändern sich einige Attribute in der Basistabelle A (für 15 bis 20 Datensätze) alle 20 Sekunden. Auf dieser Grundlage muss ich einige Werte für alle diese Variationsdatensätze in Tabelle B für neu berechnen Alle Nutzer. Obwohl sich nur 20 Stammdatensätze ändern, muss ich 200.000 Benutzerdatensätze neu berechnen und aktualisieren, was mehr als 20 Sekunden dauert. Bis dahin erfolgt die nächste Aktualisierung schließlich, sodass alle Select-Abfragen in die Warteschlange gestellt werden. Ich erhalte ungefähr 3 Anfragen / 5 Sekunden von Online-Benutzern, was zu 6-9 ausgewählten Abfragen führt. Um auf eine API-Anfrage zu antworten, verwende ich immer die Felder in Tabelle B.

Ich kann mehr Rechenleistung kaufen und diese Situation lösen, aber ich bin an einem richtig skalierten System interessiert, das sogar eine Million Benutzer verarbeiten kann.

Kann hier jemand eine bessere Alternative vorschlagen? Hilft mir die relationale Datenbank nosql + hier? Gibt es Plattformen / Datenspeicher, mit denen ich Daten häufig aktualisieren kann, ohne sie zu sperren, und die mir gleichzeitig die Flexibilität geben, ausgewählte Abfragen für verschiedene Felder in einer Entität auszuführen?

Krüge
quelle
Müssen Sie wirklich all diese Daten speichern? Das klingt irgendwie so, als ob Sie besser auf Anfrage rechnen sollten. Wenn Sie 200.000 Datensätze in etwas mehr als 20 Sekunden berechnen können, sollte es möglich sein, diese 20 Datensätze * 3 Benutzer = 60 Datensätze in kürzester Zeit zu berechnen. Möglicherweise könnten Sie schauen, welche Benutzer zu welchem ​​Zeitpunkt online sind, und noch mehr optimieren? Sieht ein bisschen so aus, als würden Sie Tonnen von Daten generieren, die niemand jemals verwendet (während der Zeit, in der die Daten noch gültig sind)
Thorsten Müller
Das Generieren nur für die angemeldeten Benutzer ist eine sehr gute Option. Ich habe auch darüber nachgedacht, aber es ist immer noch kein skalierbarer Ansatz. Meine Plattform wird nur tagsüber verwendet und daher sind während dieser Zeit die meisten Benutzer aktiv. Irgendwelche anderen Vorschläge Kumpel?
Krüge
@Jugs - Damit bleibt immer noch die Frage, ob Sie nur im laufenden Betrieb rechnen können. Haben Sie haben , um die Datensätze zu aktualisieren, oder hat Ihre Anwendung nur die Daten benötigen , dort zu sein?
Bobson
Ich fürchte, ich kann nicht im laufenden Betrieb rechnen, da die Eintragstabelle B für einen Benutzer (5 Sterne bis 1 Stern) eingestuft ist. Nachdem diese Berechnungen abgeschlossen sind, führen wir die Rangfolge für den Benutzer erneut durch. Der gesamte Prozess für einen Benutzer dauert 500 ms und wenn ich es im laufenden Betrieb mache, wirkt sich dies auf unsere API-Antwortzeit aus
Jugs
Ich dachte, wenn es sinnvoll ist, die Punktzahlen und Ranglisten außerhalb von RDBMS zu speichern, befinden sie sich möglicherweise in einer nosql-Datenbank, sodass ausgewählte Anweisungen weiterhin ohne Probleme ausgeführt werden. Manchmal muss ich jedoch auch die Punktzahlen und die Ranglisten abfragen. Also bin ich im Moment irgendwie verloren, weshalb ich nach Ratschlägen von einigen Experten wie euch suche
Jugs

Antworten:

1

Sieht aus wie die Tabelle Beine Art Cache ist. Aber diese Art von Cache, der die Produktivität senkt.

Selbst wenn Sie 25 Anfragen pro Sekunde haben, können Sie die Verwendung der Tabelle ablehnenB und die Antwort für jede Anfrage berechnen.

Wie auch immer , wenn Sie 30 Sekunden Verzögerung haben 20 Aufzeichnungen über die Aktualisierung - es ist ein nicht in einer Softwarearchitektur (ich bin falsch, wenn Ihre DB für jeden Datensatz ersten 10 ^ 100 Anzeichen von PI berechnet).

Wie ich weiß, funktioniert die relationale Datenbank ohne hässliche SQL-Abfragen, mit Indizes und mit weniger als 1 000 000 Datensätzen für fast alle Abfragen perfekt.

Versuchen Sie, die Verwendung von Tabellen zu verweigern Bund Ihrer Tabelle entsprechende Indizes hinzuzufügen A(die meisten modernen Datenbanken verfügen über ein Hilfsprogramm). Weiter: Versuchen Sie, die Struktur von Daten (Tabelle A) und einer Abfrage (mithilfe des Abfrageanalysators oder mit SQL-Experten) zu optimieren , um die Berechnung zu beschleunigen. Wenn Sie aktualisieren nur 20 Datensätze - die Existenz von Indizes nicht die Produktivität eines schaden Update Prozess, aber deutlich verbessert wählen Geschwindigkeit.

maxkoryukov
quelle
1

Die Frage ist wirklich, welches System den in B einzufügenden Datensatz und die Größe der B-Daten berechnet.

Jede Datenbank (z. B. MSSQL) sollte in der Lage sein, das Volumen der Einfügungen, von denen Sie sprechen, problemlos zu verarbeiten, vorausgesetzt, das Objekt ist nicht riesig.

Aktualisierungen können durch ein schwierigeres Problem erfolgen, aber mit der richtigen Indizierung und Sperrung sollte dies wiederum kein großes Problem sein.

In 99% der Fälle, in denen ich ein solches Problem sehe, liegt es daran, dass der B-Datensatz von einem gespeicherten Prozess berechnet wird. Dadurch wird der Datenbankserver vollständig belastet

In diesem Fall besteht die Lösung darin, diesen Code in einen Offline-Dienst zu verschieben, der über ein Warteschlangensystem aufgerufen werden kann.

Ihre Update A-Nachricht würde also einen Worker-Prozess auslösen, der die Benutzer durchläuft und für jeden Benutzer eine Update B-Nachricht erstellt

Ein zweiter Arbeitsprozess B würde das Update Benutzer X mit Daten A abholen. Das Ereignis B erstellt den B-Datensatz und aktualisiert die Datenbank

Dies kann skaliert werden, indem mehr Felder mit Warteschlangenarbeitern hinzugefügt werden, sodass Sie immer mehr Rechenleistung hinter der Berechnung haben und Ihre Datenbank sich auf Aktualisierungen und Auswahlen konzentrieren kann.

Sie können weiter optimieren, indem Sie die Auswahl von den Aktualisierungen / Einfügungen trennen. Haben Sie eine neue Datenbank, die alle Auswahlanforderungen als Replikations-Slave erhält, die alte Datenbank, die alle Aktualisierungen erhält.

Ewan
quelle
0

Wenn Sie in Amazon laufen, würde ich DynamoDB in Betracht ziehen. Es basiert auf Flash-Speicher. Hier ist ein Link dazu: https://aws.amazon.com/dynamodb/ .

Welche Arten von RDBMS verwenden Sie? Möglicherweise können Sie die Leistung mithilfe einer UDF oder eines berechneten Felds in einer Ansicht steigern. Führen Sie die Berechnung in der Datenbank über eine einzelne Aktualisierungsabfrage aus oder wählen Sie die Daten aus der Datenbank aus, führen Sie die Berechnungen in einem anderen Prozess aus und laden Sie sie dann wieder in die Datenbank?

Oracle ist standardmäßig so konfiguriert, dass die Ausführung im Snapshot-Modus verwendet wird. Dies bedeutet, dass die Zeilen während der Aktualisierung nicht gesperrt werden und gleichzeitige Auswahlen den ursprünglichen Wert erhalten. SQL Server ist standardmäßig mit pessimistischer Parallelität konfiguriert, sodass gleichzeitige Auswahlen blockiert werden, bis das Update abgeschlossen ist. Einige Versionen von SQL Server können in den Snapshot-Modus versetzt werden, dies erhöht jedoch die Belastung der temporären Tabelle erheblich.

In welcher Umgebung laufen Sie? Wenn es sich um ein RDBMS auf einer EC2-Instanz in Amazon handelt, versuchen Sie, die DB-Datendateien auf der lokalen Flash-Festplatte abzulegen. Ich habe einen Größenordnungsunterschied beim Verschieben der Dateien von EBS auf die lokale Festplatte festgestellt.

Robert-Ryan.
quelle