Hintergrund :
Ich habe eine Webanwendung erstellt, die ich relativ gut skalieren möchte. Ich weiß, dass ich nicht Google oder Twitter bin, aber meine App verwendet eine ziemlich große Datenmenge für jeden Benutzer und hat daher ziemlich hohe Datenanforderungen. Ich möchte bereit sein, einigermaßen gut zu skalieren, ohne später alles neu entwerfen zu müssen.
Ich betrachte mich als Softwareentwickler, nicht als Datenbankexperte. Deshalb poste ich hier. Hoffentlich kann mir jemand mit viel mehr Datenbankkenntnissen Ratschläge geben.
Mit einer relativ großen Anzahl von Benutzern, aber nichts wie Facebook-Nummern, erwarte ich eine Datenbank, die so aussieht:
Ein "großer Tisch":
- 250 Millionen Datensätze
- 20 Spalten
- Ungefähr 100 GB Daten
- Hat einen indizierten Bigint (20) Fremdschlüssel
- Hat eine indizierte varchar (500) string_id-Spalte
- Hat eine int (11) "Wert" -Spalte
4 weitere Tabellen:
- Jeweils 10 Millionen Datensätze
- Jeweils ca. 2 - 4 GB Daten
- Jede dieser Tabellen hat 4 - 8 Spalten
- Eine Spalte ist datetime date_created
- Eine Spalte ist die Spalte varchar (500) string_id
- In einem Join werden eine oder zwei Spalten aus jeder dieser Tabellen ausgewählt
Eine dieser Tabellen wird zum Speichern von Durchschnittswerten verwendet. Das Schema lautet bigint (20) id, varchar (20) string_id, datetime date_created, float durchschnitt_value
Was ich tun möchte - zwei relativ teure Abfragen:
Berechnen Sie neue Durchschnittswerte:
- Wählen Sie mit einem Fremdschlüssel bis zu mehrere Millionen separate Datensätze aus der großen Tabelle aus.
- Berechnen Sie einen neuen Durchschnitt, gruppieren Sie nach der string_id.
- Fügen Sie die Ergebnisse in die Durchschnittstabelle ein.
- Wie derzeit erstellt, verwendet diese Abfrage zwei Verknüpfungen.
Erstellen Sie de-normalisierte, schreibgeschützte Datensätze für Benutzer:
- Verwenden Sie einen Fremdschlüssel, um zwischen 1.000 und 40.000 Datensätze aus der großen Tabelle auszuwählen.
- Verbinden Sie sich mit jeder der anderen vier Tabellen im neuesten Datensatz mit der Zeichenfolgen-ID-Spalte.
- Fügen Sie die Ergebnisse in eine de-normalisierte Tabelle ein.
- Diese Datensätze werden vom Front-End verwendet, um Benutzern Informationen anzuzeigen.
- Wie derzeit erstellt, verwendet diese Abfrage vier Verknüpfungen.
Ich plane, jede dieser teuren Abfragen in einer Batch-Back-End-Datenbank auszuführen, die ihre Ergebnisse an einen Echtzeit-Front-End-DB-Server überträgt, der Anforderungen von Benutzern verarbeitet. Diese Abfragen werden in regelmäßigen Abständen ausgeführt. Ich habe nicht entschieden, wie oft. Die durchschnittliche Abfrage könnte möglicherweise einmal pro Tag durchgeführt werden. Die De-Normalisierungsabfrage muss häufiger ausgeführt werden - möglicherweise alle paar Minuten.
Jede dieser Abfragen wird derzeit in MySQL in wenigen Sekunden auf einem sehr einfachen Computer mit einem Datensatz mit 100.000 Datensätzen in der „großen Tabelle“ ausgeführt. Ich bin sowohl besorgt über meine Skalierbarkeit als auch über die Kosten der Skalierung.
Fragen :
- Scheint dieser Ansatz sinnvoll? Stimmt etwas aus einer Gesamtperspektive offensichtlich nicht?
- Ist ein RDBMS das richtige Tool, oder sollte ich mir andere "Big Data" -Lösungen wie die der Hadoop-Familie ansehen? Meine Neigung ist es, ein RDBMS zu verwenden, da die Daten strukturiert sind und gut in das relationale Modell passen. Ab einem bestimmten Punkt kann ich jedoch möglicherweise kein RDBMS mehr verwenden. Ist das wahr? Wann würde dieser Schalter benötigt?
- Wird es funktionieren? Können diese Abfragen in angemessener Zeit ausgeführt werden? Ich kann vielleicht Stunden auf Abfrage Nr. 1 warten, aber Abfrage Nr. 2 sollte in Minuten abgeschlossen sein.
- Was muss ich aus Hardware-Sicht beachten? Was sind meine RAM- und CPU-Engpässe wahrscheinlich? Ich gehe davon aus, dass es wichtig ist, Indizes im RAM zu halten. Gibt es noch etwas, das ich berücksichtigen sollte?
- Irgendwann muss ich wahrscheinlich meine Daten partitionieren und mehrere Server verwenden. Scheint mein Anwendungsfall bereits in dieser Kategorie zu sein, oder kann ich eine einzelne Maschine für eine Weile vertikal skalieren? Funktioniert das mit dem 10-fachen der Daten? 100x?