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?
quelle
Antworten:
Sieht aus wie die Tabelle
B
eine 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 ablehnen
B
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
B
und Ihrer Tabelle entsprechende Indizes hinzuzufügenA
(die meisten modernen Datenbanken verfügen über ein Hilfsprogramm). Weiter: Versuchen Sie, die Struktur von Daten (TabelleA
) 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.quelle
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.
quelle
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.
quelle