2009-10-04 2 views
10

Vor einiger Zeit dachte ich, ein neues Statistiksystem für unsere Multi-Millionen-Benutzer-Website, um Benutzeraktionen für unsere Kunden zu protokollieren und zu melden.30 Millionen Datensätze pro Tag, SQL Server kann nicht mithalten, andere Arten von Datenbanksystemen benötigt?

Das Datenbank-Design ist recht einfach und enthält eine Tabelle mit einer foreignId (200.000 verschiedene IDs), einem datetime-Feld, einer actionId (30 verschiedene IDs) und zwei weiteren Feldern mit einigen Meta-Informationen (nur kleine). . Für andere Tabellen gibt es keine Einschränkungen. Außerdem haben wir zwei Indizes, die jeweils 4 Felder enthalten, die nicht gelöscht werden können, da die Benutzer bei kleineren Indizes Timeouts erhalten. Die foreignId ist das wichtigste Feld, da jede Abfrage dieses Feld enthält.

Wir haben uns für den SQL Server entschieden, aber nach der Implementierung scheint eine relationale Datenbank nicht perfekt zu passen, da wir 30 Millionen Datensätze pro Tag nicht einfügen können (es ist nur Einfügung, wir machen keine Updates) viel zufällige Lesevorgänge in der Datenbank; weil die Indizes nicht schnell genug aktualisiert werden können. Ergo: Wir haben ein massives Problem :-) Wir haben das Problem vorübergehend gelöst, aber

eine relationale Datenbank scheint nicht für dieses Problem geeignet sein!

Wäre eine Datenbank wie BigTable eine bessere Wahl, und warum? Oder gibt es andere, bessere Entscheidungen im Umgang mit dieser Art von Problemen?

NB. An dieser Stelle verwenden wir ein einzelnes 8-Kern-Xeon-System mit 4 GB Speicher und Win 2003 32-Bit. RAID10 SCSI soweit ich weiß. Die Indexgröße beträgt etwa das 1,5-fache der Tabellengröße.

+0

Was meinst du damit, dass es "nicht mithalten kann?" Was scheitert? Ist Netzwerk-E/A ein Problem? Sind Sie an CPU-Auslastung gebunden? Reagiert es bei normaler Nutzung auf allen Hardwaresystemen nicht schnell genug? Dies kann ein Serverproblem sein. Was sind Ihre DB-Serverspezifikationen? –

+0

Sein Problem scheint ein Ergebnis des Index-Overheads zu sein. Er kann seine Indizes nicht loswerden, aber das Aktualisieren von Indizes auf einem riesigen Tisch 30 Millionen Mal am Tag ist teuer. – timdev

+4

Es gibt keinen Grund, warum SQL Server dies nicht kann. Ich muss entweder feststellen, dass entweder das Datendesign oder die Konfiguration das Problem ist. Können Sie uns bitte das CREATE-Skript der Tabelle zusammen mit den Schlüsseln und Indizes sowie den Indizes für die beiden verwandten Tabellen zeigen? – RBarryYoung

Antwort

11

Sie sagen, dass Ihr System 3000 Datensätze pro Sekunde ohne Indizes, aber nur etwa 100 mit zwei zusätzlichen nicht gruppierten Indizes einfügen kann. Wenn 3k/s der maximale Durchsatz ist, den Ihre E/A ermöglicht, sollte theoretisch der Durchsatz durch Hinzufügen von zwei Indizes auf etwa 1000-1500/Sek. Reduziert werden. Stattdessen sehen Sie eine Verschlechterung 10 Mal schlechter. Die richtige Lösung und Antwort lautet "Es hängt ab" und einige ernsthafte Problemlösungen und Engpässe müssen identifiziert werden. In diesem Sinne, wenn ich eine Vermutung wagen würde, würde ich zwei mögliche Täter geben:

A. Die zusätzlichen nicht geclusterten Indizes verteilen die Schreibvorgänge von schmutzigen Seiten in mehr Zuordnungsbereiche. Die Lösung wäre, den Clustered-Index und jeden Nicht-Clustered-Index in eine eigene Dateigruppe zu platzieren und die drei Dateigruppen jeweils auf separaten LUNs auf dem RAID zu platzieren.

B. Die geringe Selektivität der nicht gruppierten Indizes führt zu hohen Konflikten zwischen Lese- und Schreibvorgängen (Schlüsselkonflikte sowie %lockres% conflicts), was zu langen Sperrwartezeiten sowohl für Einfügungen als auch für Auswahlvorgänge führt. Mögliche Lösungen wären die Verwendung von SNAPSHOTs mit read committed snapshot mode, aber ich muss vor der Gefahr warnen, Lot von IO in der version store (dh in tempdb) auf System, das bereits unter hoher IO-Belastung sein kann, hinzuzufügen. Eine zweite Lösung verwendet database snapshots für die Berichterstellung, sie verursachen weniger IO Stress und sie können besser kontrolliert werden (kein Tempdb Versionsspeicher beteiligt), aber die Berichterstattung ist nicht mehr auf Echtzeitdaten.

Ich neige zu glauben, B) als die wahrscheinliche Ursache, aber ich muss wieder betonen, die Notwendigkeit für eine ordnungsgemäße Untersuchung und ordnungsgemäße Root-Fall-Analyse.

"RAID10" ist keine sehr genaue Beschreibung.

  • Wie viele Spindeln im RAID 0 Teil? Sind sie kurz gestreift?
  • Wie viele LUNs?
  • Wo befindet sich das Datenbankprotokoll?
  • Wo befindet sich die Datenbank?
  • Wie viele Partitionen?
  • Wo befindet sich Tempdb?

Wie auf die Frage, ob relationale Datenbanken für so etwas geeignet sind, ja, absolut.Es gibt viel mehr Faktoren zu berücksichtigen, Wiederherstellbarkeit, Verfügbarkeit, Toolset-Ökosystem, Know-how-Know-how, einfache Entwicklung, einfache Bereitstellung, einfache Verwaltung und so weiter und so weiter. Relationale Datenbanken können Ihre Arbeitslast leicht bewältigen, sie brauchen nur die richtige Abstimmung. 30 Millionen Einsätze pro Tag, 350 pro Sekunde, sind kleine Änderungen für einen Datenbankserver. Aber ein 32bit 4GB RAM System kaum ein Datenbankserver, unabhängig von der Anzahl der CPUs.

2

Sie liefern nicht genügend Informationen; Ich bin nicht sicher, warum Sie sagen, dass eine relationale Datenbank scheint eine schlechte Passform, abgesehen von der Tatsache, dass Sie jetzt Leistungsprobleme haben. Auf welcher Art von Maschine läuft das RDBMS? Angesichts der Tatsache, dass Sie ausländische IDs haben, scheint es, dass eine relationale Datenbank genau ist, was hier genannt wird. SQL Server sollte in der Lage sein, 30 Millionen Einfügungen pro Tag zu verarbeiten, vorausgesetzt, dass es auf ausreichender Hardware ausgeführt wird.

+0

Wir kümmern uns wirklich nicht um relationale Integrität. Die Inserts sind schnell genug, aber die Indizes können nicht schnell genug aktualisiert werden. –

7

Es klingt, als könnten Sie unter zwei besonderen Problemen leiden. Das erste Problem, das Sie haben, ist, dass Ihre Indizes jedes Mal neu erstellt werden müssen, wenn Sie eine Einfügung durchführen - versuchen Sie wirklich, Live-Berichte eines Transaktionsservers auszuführen (dies wird normalerweise als Nein-Nein betrachtet)? Zweitens können Sie auch Probleme mit dem Server haben, der die Größe der Datenbank ändern muss. Stellen Sie sicher, dass Sie genügend Speicherplatz zugewiesen haben und sich nicht auf die Datenbank verlassen, um dies für Sie zu tun.

Haben Sie darüber nachgedacht, etwas wie indizierte Sichten in SQL Server zu untersuchen? Sie sind eine gute Möglichkeit, die Indizierung aus der Haupttabelle zu entfernen und in eine materialisierte Ansicht zu verschieben.

+1

+1 Ich habe gerade etwas Ähnliches eingegeben. – timdev

+0

Going, um die indizierte Sicht zu testen. Daran hatte ich selbst nicht gedacht. –

+2

indizierte Sicht = mehr Indizes ... – gbn

0

Sybase IQ scheint ziemlich gut für das Ziel zu sein, wie unsere Architekten/DBAs gezeigt haben (wie in, sie bewegen ausdrücklich alle unsere Statistiken auf IQ, die diese Fähigkeit als der Grund angeben). Ich kann mich jedoch nicht begründen - nicken nur die Leute in unserer Firma an, die im Allgemeinen wissen, wovon sie aus vergangenen Erfahrungen sprechen.

Wie auch immer, ich frage mich, ob Sie alle 30mm Datensätze speichern müssen? Wäre es nicht besser, einige voraggregierte Daten zu speichern?

+0

Gut zu diesem Zeitpunkt verwenden wir eine Staging-Tabelle, und aggregieren die Daten in der Nacht und Bulk fügen Sie diese in die Haupttabelle (Entfernen der Indizes, und fügen Sie sie anschließend). Aber wir möchten die Aktionen auf der Site in Echtzeit sehen. –

3

Sie könnten versuchen, die Tabelle eine partitioned one machen. Auf diese Weise wirken sich die Indexaktualisierungen auf kleinere Sätze von Zeilen aus. Wahrscheinlich wird eine tägliche Partitionierung ausreichen. Wenn nicht, versuchen Sie es nach Stunden zu partitionieren!

2

Die Replikation der Datenbank für die Berichterstellung scheint bei starkem Verkehr die beste Route zu sein.Allerdings, ein paar Dinge zuerst zu versuchen ...

Gehen Sie mit einem einzigen Index, nicht zwei Indizes. Ein gruppierter Index wird wahrscheinlich eine bessere Wahl sein als ein nicht gruppierter Index. Weniger, breitere Indizes werden im Allgemeinen besser als mehr, schmalere Indizes. Und wie du sagst, ist es die Indizierung, die deine App umbringt.

Sie sagen nicht, was Sie für IDs verwenden, aber wenn Sie GUIDs verwenden, möchten Sie möglicherweise Ihre Schlüssel auf bigints umstellen. Da GUIDs zufällig sind, belasten sie Indizes sowohl beim Erstellen von Indizes als auch beim Verwenden von Indizes. Durch die Verwendung einer Bigint-Identitätsspalte wird der Index ziemlich chronologisch ablaufen. Wenn Sie wirklich an Echtzeitzugriff auf Abfragen in Ihren letzten Daten interessiert sind, ist Ihr Zugriffsmuster viel besser für monoton wachsende Schlüssel geeignet.

+0

Ja, das klingt definitiv nach dem besten Ansatz; eine Kopie der Datenbank ohne Indizes für alle Einsätze und eine replizierte Kopie mit den Indizes für das Reporting.Auf diese Weise behindern die Indizes die laufenden Aktualisierungen nicht. –

0

Nicht sicher über SQL Server, aber in einem anderen Datenbanksystem, das ich vor langer Zeit verwendet habe, war die ideale Methode für diese Art Aktivität, die Updates zu speichern und dann als Batch die Indizes zu deaktivieren, die neuen Datensätze hinzuzufügen und neu zu indizieren. Wir haben das einmal pro Nacht gemacht. Ich bin mir nicht sicher, ob Ihre Berichtsanforderungen für diese Art von Lösung geeignet sind oder ob dies in MS SQL möglich ist, aber ich denke, das könnte es.

+0

Wir machen dies als Workaround, da wir mit ernsthaften Problemen konfrontiert waren. Aber ich würde einen Echtzeitansatz bevorzugen. –

0

Sie sagen nicht, wie die Inserts verwaltet werden. Sind sie stapelweise oder wird jede Statistik separat geschrieben? Denn das Einfügen von eintausend Zeilen in einer einzigen Operation wäre wahrscheinlich viel effizienter als das Einfügen einer einzelnen Zeile in tausend separate Operationen. Sie könnten immer noch häufig genug einfügen, um mehr oder weniger Echtzeit-Reporting anzubieten;)

Verwandte Themen