15 Stimmen

Datenbankdesign für schreibintensive Webanwendungen

Viele der LOB-Anwendungen, die wir unseren Kunden zur Verfügung stellen, haben einen Marketing-/Werbecharakter (Gewinnspiele, Veranstaltungsregistrierung, etc.). Die meisten dieser Anwendungen sind zwar sehr einfach, stellen aber sehr hohe Anforderungen an die Datenbank. Stellen Sie sich eine Website vom Typ "Registrierung" als Hintergrund für einen Werbespot vor, der beispielsweise während des Superbowls ausgestrahlt wird (ja, wir hatten schon mehrere).

Obwohl wir bei der Optimierung des Codes unserer Webanwendungen sehr gut geworden sind, bleibt die Datenbank immer ein Problem, obwohl die Anwendung relativ einfach ist. Der Ablauf ist typischerweise in etwa so:

  1. Aus der Datenbank lesen, um vorhandene Datensätze zu erkennen
  2. In die Datenbank schreiben, wenn der Datensatz neu ist

In vielen Fällen ist dies der einzige Datenzugriff, den unsere Anwendung durchführen muss. Da dies jedoch der einzige Zweck der Anwendung ist, ist es sehr wichtig, dass dieser einfache Prozess stark optimiert wird.

Für die Zwecke dieser Frage haben wir einen einzelnen Server mit einem Raid-5-Platten-Array für die Datendateien und einem weiteren Raid-5-Array für die Protokolle. Das Betriebssystem ist zur Zeit Windows 2003 Standard 32bit und der Server hat 4 GB Speicher. Einige Anwendungen verwenden SQL 2005 Standard, während andere MySQL 5.1 verwenden. Ich bin sehr bewusst Ich weiß, dass bestimmte Betriebssystem- und Hardware-Optimierungen hier möglich sind, aber ich möchte meine Bedürfnisse zuerst von der Software-Seite her angehen. Ausführliches Profiling hat uns gelehrt, dass Festplatten-IO ist im Allgemeinen der größte Engpass .

Nachdem ich all das gesagt habe und weiß, dass Caching nicht viel helfen wird, da die meisten Lesevorgänge einmalig sind und nur sehr wenige Daten zurückgeben (oft nur ein bisschen, das angibt, ob ein Datensatz existiert oder nicht), überlege ich, einen Sprung in den Bereich der In-Memory-Datenbanken als eine Art Schreib-Cache-Schicht für die echte Datenbank zu machen. Dies scheint eine gute Lösung zu sein, da der Großteil unseres hohen Datenaufkommens sporadischer Natur ist und sich nicht über mehrere Stunden hinzieht. Außerdem wäre der mögliche Verlust von ein paar Minuten an Daten aufgrund eines Serverabsturzes in den meisten Fällen akzeptabel.

In der einfachsten Form würde ich eine typische Registrierungsanwendung so ändern, dass sie Folgendes tut:

  1. Abfrage der Festplatten-DB und der Speicher-DB nach vorhandenen Datensätzen
  2. Wenn nicht, werden Daten in den Speicher-DB geschrieben und zurückgegeben
  3. Regelmäßiges Flushen der Speicher-DB auf die Festplatten-DB

Meine Frage lautet Was sind meine Optionen für diese In-Memory-Datenbank? Ich habe mit In-Memory-Hashtabellen, Datentabellen und dergleichen experimentiert, aber ich bin auf der Suche nach anderen Optionen oder sogar Vorschläge für einen völlig anderen Ansatz.

1voto

Jens Schauder Punkte 70079

Ich weiß nicht, wie es sich mit den von Ihnen erwähnten Datenbanken verhält, aber wenn der Inhalt der Datenbank (oder zumindest die wichtige Tabelle) in den Arbeitsspeicher passt, kann Oracle ihn im Cache ablegen, so dass er sich im Grunde wie eine In-Memory-Datenbank verhält.

Ich würde auch die Einstellungen der Isolationsebene Ihrer Datenbank überprüfen. Wenn Sie in der Lage sind, diese zu lockern, können Sie möglicherweise die Sperrung reduzieren.

Ziehen Sie schließlich in Erwägung, einmalige Beschränkungen zu entfernen oder sie für die Spitzenzeiten zu deaktivieren.

1voto

Meiner Meinung nach sollten Sie in der Lage sein, Ihre Arbeitslast mit einem RDBMS zu bewältigen, das über einen Cache verfügt, dessen Größe vom Benutzer eingestellt werden kann. Ich sehe in der Größenordnung von 10000 indizierten Datensätzen pro Sekunde mit einem einfachen C++-aufrufbaren RDBMS mit gewöhnlicher Hardware. Das schließt die Übertragung auf die Festplatte ein. Da Sie möglicherweise nur ein kleines Feld in einem Datensatz betrachten, sollten Sie sich für eine spaltenorientierte Datenbank entscheiden - eine, die Daten spaltenweise speichert. Es macht keinen Sinn, eine ganze Zeile einzulesen, wenn Sie nur an einem Feld interessiert sind.

1voto

Mike Punkte 276

Die Optimierung Ihres Datenbankschemas für Schreibvorgänge anstelle von Lesevorgängen, wie von vielen anderen erwähnt, ist Ihre erste Anlaufstelle, auch wenn Sie das vermutlich schon getan haben

Bevor Sie sich mit In-Memory-Datenbanken beschäftigen, sollten Sie einen Blick auf einige der verfügbaren ORMs werfen, insbesondere NHibernate.

NHibernate hält einige Daten im Speicher und ermöglicht Ihnen eine gewisse Kontrolle darüber, wann die Datenaktualisierungen aus dem Speicher "gespült" und mit der Datenbank synchronisiert werden.

Es könnte sich lohnen, einen Blick darauf zu werfen.

1voto

hythlodayr Punkte 2367

Bearbeiten: Ich konzentriere mich ausschließlich auf die Festplatten-E/A...

  1. Streichen Sie so viele unnötige Indizes wie möglich. Indizes gibt es nicht umsonst - weder Platz noch Zeit.
  2. Streichen Sie alle speziellen Auslöser oder Beschränkungen, die Sie nicht benötigen.
  3. Streichen Sie alle Entitätsbeziehungen/relationalen Integritätsoperatoren, die nicht unbedingt erforderlich sind.
  4. Wenn Ihr aktuelles DBMS dies unterstützt, verteilen Sie die Transaktionstabellen auf mehrere Platten (z.B. Round-Robin).
  5. Sie erwägen, weitere Datenbankserver unabhängig voneinander hinzuzufügen (d.h. ohne Replikation); dazu benötigen Sie einen Scheduler, der entscheidet, welcher Server die Transaktion annimmt, und ein Schema/einen separaten Prozess, der die Transaktionen konsolidiert.

Die Minimierung des Umfangs der Datenbanklogik und das spätere Hinzufügen von Servern (im Gegensatz zu hochmoderner Servertechnologie) ist im Grunde der Ansatz von ebay.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X