Datenbankentwurf für eine umfangreiche Webanwendung

9

Viele der LOB-Anwendungen, die wir unseren Kunden anbieten, sind Marketing- / Werbezwecke (Gewinnspiele, Registrierung von Veranstaltungen usw.). Die meisten Anwendungen, obwohl sehr einfach, sind sehr anspruchsvoll in der Datenbank. Stellen Sie sich eine Seite mit "Registrierung" als Hintergrund für einen Werbespot vor, der zum Beispiel während des Superbowls ausgestrahlt wird (ja, wir hatten mehrere).

Obwohl wir sehr gut darin sind, unseren Web-App-Code zu optimieren, bleibt die Datenbank immer ein Problem, obwohl die Anwendung relativ einfach ist. Der Ablauf ist typischerweise etwas wie:

  1. Aus Datenbank lesen, um vorhandenen Datensatz zu erkennen
  2. Schreiben Sie in die Datenbank, wenn der Datensatz neu ist

In vielen Fällen ist dies der gesamte Datenzugriff, den unsere Anwendung ausführen muss. Da es 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, auf dem ein RAID-5-Array für die Datendateien und ein RAID-5-Array für die Protokolle ausgeführt wird. Zu diesem Zeitpunkt ist das Betriebssystem Windows 2003 Standard 32 Bit und der Server verfügt über 4 GB Arbeitsspeicher. Einige Apps verwenden den SQL 2005-Standard, andere verwenden MySQL 5.1. Ich bin mir sehr wohl bewusst, dass bestimmte Betriebssystem- und Hardware-Optimierungen hier möglich sind, aber ich möchte zuerst meine Bedürfnisse von einer Software-Seite aus ansprechen. Umfangreiches Profiling hat uns gezeigt, dass disk IO im Allgemeinen der größte Engpass ist.

Nachdem wir all das gesagt haben und wissen, dass Caching nicht viel hilft, da die meisten Lesevorgänge einzigartig sind und sehr wenig Daten zurückgeben (oft nur ein bisschen, ob ein Datensatz existiert oder nicht), überlege ich, einen Sprung in die Bereich von In-Memory-Datenbanken als eine Art von Cache-Cache-Schicht in der realen Datenbank. Dies scheint eine gute Lösung zu sein, da der Großteil unseres Verkehrs mit hohem Volumen sporadisch ist und nicht über mehrere Stunden aufrechterhalten wird. Darüber hinaus wäre der potenzielle Verlust von Daten in wenigen Minuten aufgrund eines Serverabsturzes in den meisten Fällen akzeptabel.

In der einfachsten Form würde ich eine typische Registrierungs-App ändern, um Folgendes zu tun:

  1. Abfrage der Platten-DB und der Speicher-DB nach vorhandenen Datensätzen
  2. Falls nicht, schreibe Daten in die Speicher-DB und gib
  3. zurück
  4. Spülung des Speicher-DBs regelmäßig auf die Disk-DB

Meine Frage ist : Was sind meine Optionen für diese Zwischenspeicher-Datenbank? Ich habe mit In-Memory-Hashtabellen, Datentabellen usw. experimentiert, aber ich suche nach anderen Optionen oder sogar Vorschlägen für einen ganz anderen Ansatz.

    
Chris 04.11.2009, 16:41
quelle

9 Antworten

4

Nehmen Sie den neuen Begriff "Alles ist eine Nachricht, Datenbank ist das Backup" auf. Wenn Sie etwas zu speichern haben, erstellen Sie eine Nachricht und senden Sie sie mithilfe von XMPP an eine Blackbox (wie eJabberD). Lassen Sie die Blackbox Ihre Datenbank nach einem eigenen Zeitplan aktualisieren. So funktionieren Websites wie Twitter.

Sehen Sie sich diese Diashow an: Ссылка

    
srini.venigalla 04.11.2009, 19:14
quelle
7

Wenn Sie nicht wissen müssen, ob ein Datensatz in Echtzeit existiert (dh es ist wichtig, dass der Datensatz dort ankommt, aber Sie müssen nicht melden, ob er für den Benutzer neu oder vorhanden war) Sie können Ihre Datenbank so strukturieren, dass extrem schnelle Schreibzeiten möglich sind, ohne dass eine In-Memory-Datenbank benötigt wird, die viele potenzielle Probleme mit sich bringt, wenn Server ausfallen oder Worker-Prozesse neu gestartet werden.

Erstellen Sie zwei Tabellen in Ihrer Datenbank für jede Tabelle, die an diesem starken Schreibfluss beteiligt sind. Eine Tabelle sollte Ihre "Live" -Tabelle sein und so weit wie möglich schreiboptimiert sein (d. H. Keine Indizes und wird nie gelesen, außer wenn Sie in die Lesetabelle wechseln). Ihre andere Tabelle sollte Ihre für das Lesen optimierte Tabelle sein, die für alle Berichtserwägungen usw. indiziert ist.

Wenn Sie in Ihre Live-Tabelle schreiben, ignorieren Sie alles, was damit zu tun hat, ob ein Datensatz neu oder vorhanden ist oder irgendetwas darüber hinausgeht, diese Daten so schnell wie möglich in die Tabelle zu bekommen und aus der Datenbank herauszukommen. Richten Sie einen geplanten Job ein, der Datensätze aus der Live-Tabelle in die für den Lesevorgang optimierte Tabelle verschiebt, und sorgen Sie dafür, dass vorhandene Datensätze dort zusammengeführt werden. Idealerweise wird dies zu Zeiten außerhalb der Spitzenzeiten durchgeführt, ansonsten sollten Sie jedoch eine dritte Staging-Tabelle in Erwägung ziehen, damit zu keinem Zeitpunkt Konflikte in der Live-Tabelle auftreten.

    
Ryan Brunner 04.11.2009 16:49
quelle
2

Nicht im Zusammenhang mit der Programmierung, würde aber definitiv helfen: Holen Sie sich einige der neueren Solid State Disks.

Ja, sie sind teuer für die Größe, aber da Disk IO der Engpass ist, würde das Austauschen der aktuellen HDDs für einige SSDs die Leistung erheblich verbessern.

    
Neil N 04.11.2009 18:59
quelle
2

Hier ist eine seltsame Idee: Verwenden Sie keine Datenbank für die anfängliche Erfassung. Entwirf zwei oder drei schreiend schnelle indizierte Dateien, deren Format sich nicht oft ändern muss. Erfassen Sie die Daten in diesen Dateien.

Schreiben Sie eine entsprechend ausgelöste Software, die erfasste Daten in eine Datenbank kopiert, den interaktiven Benutzer jedoch nicht verzögert. Markieren Sie kopierte Daten, um doppelte Kopien zu vermeiden und Speicherplatz in der Datei wiederzuverwenden.

Nun können Sie die Datenbank so entwerfen, dass Daten zwischen mehreren Verwendungen ausgetauscht werden, anstatt mit dem Capture-Prozess Schritt zu halten. Schließlich ist das Teilen von Daten, wo Datenbanken wirklich scheinen.

    
Walter Mitty 07.11.2009 15:17
quelle
1

SQLite hat einen Arbeitsmodus im Arbeitsspeicher . Dies würde funktionieren, wenn Sie einen permanenten Serverprozess hinter Ihrem Handler für Seitenzugriffe haben.

Andernfalls können normale dateibasierte DBs dazu verleitet werden, ihre Dateien in ein Speicherdateisystem wie tmpfs zu schreiben.

    
Ewan Todd 04.11.2009 16:48
quelle
1

Aus meiner Sicht sollten Sie in der Lage sein, Ihre Arbeitslast mit einem RDBMS mit einem benutzergroßen Cache zu bewältigen. Ich sehe in der Größenordnung von 10000 indizierten Aufzeichnungen pro Sekunde mit einem einfachen C ++ - Callable RDBMS mit normaler Hardware. Dazu gehört das Festschreiben auf die Festplatte. Da Sie möglicherweise nur ein kleines Feld in einem Datensatz betrachten, suchen Sie nach einer spaltenorientierten Datenbank - einer, die Daten in der Spalte speichert. Kein Punkt beim Lesen in einer ganzen Reihe, wenn Sie nur an einem Feld interessiert sind.

    
user189321 04.11.2009 17:47
quelle
1

Die Optimierung Ihrer Datenbankschema für schreibt statt liest, wie sie von vielen anderen erwähnt, ist Ihr erster Ansprechpartner, auch wenn ich Sie es schon erraten haben

Vor dem In-Memory-Datenbanken zu untersuchen, können Sie einen Blick auf einige der ORMs haben wollen, die verfügbar sind, besonders NHibernate.

NHibernate einige Daten im Speicher hält und ermöglicht es Ihnen, eine gewisse Kontrolle über, wenn die Daten-Updates ‚gespült‘ wird aus dem Speicher und sychronised mit der Datenbank.

Vielleicht finden Sie es einen Blick wert.

    
Mike 04.11.2009 18:48
quelle
1

Edit: Konzentriere dich ausschließlich auf die Festplatten-I / O ...

  1. Ripp so viele unnötige Indizes wie möglich. Indizes kommen nicht umsonst - Raum ODER Zeit.
  2. Rippt alle speziellen Trigger oder Einschränkungen aus, die Sie nicht benötigen.
  3. Ergänzen Sie Entitätsbeziehungen / relationale Integritätsoperatoren, die nicht absolut kritisch sind.
  4. Wenn Ihr aktuelles DBMS dies unterstützt, trennen Sie die Transaktionstabellen auf mehrere Festplatten (z. B. Round-Robin).
  5. In Betracht ziehen, weitere Datenbankserver unabhängig voneinander hinzuzufügen (d. h. keine Replikation beteiligt); Dazu benötigen Sie einen Scheduler, um zu entscheiden, welcher Server die Transaktion akzeptiert, und einen Plan / separaten Prozess, der die Transaktionen konsolidiert.

Die Menge an Datenbanklogik zu minimieren und Server seitlich hinzuzufügen (im Gegensatz zu modernster Servertechnologie), ist im Prinzip der Ansatz von ebay.

    
hythlodayr 04.11.2009 19:04
quelle
0

Ich weiß nichts über die Datenbanken, die Sie erwähnen, aber wenn der Inhalt der Datenbank (oder zumindest die wichtige Tabelle) in den Speicher passt, kann oracle ihn in den Cache pinnen, so dass er sich im Grunde wie ein In verhält Speicherdatenbank.

Ich würde auch die Einstellungen für die Isolationsstufe Ihrer Datenbank prüfen. Wenn Sie in der Lage sind, diese zu lockern, können Sie die Verriegelung verringern.

Ziehen Sie zum Schluss in Betracht, eindeutige Einschränkungen zu entfernen oder sie für die Spitzenzeiten zu deaktivieren.

    
Jens Schauder 04.11.2009 17:11
quelle