Was passiert, wenn zu viele Inserts in MongoDB vorhanden sind? Wie kann sichergestellt werden, dass alle Daten gespeichert werden?

24

Ich verwende MongoDB, um periodisch gemessene Werte zu speichern. Alle ~ 100 ms wird eine Reihe von Werten als Dokument eingefügt. Es funktioniert gut, aber ich mache mir Sorgen um Leistungsprobleme. (Ich verwende sichere Einfügungen, es scheint, als wäre dies in PyMongo die Standardeinstellung.)

Was passiert, wenn mehr Einfügungen pro Sekunde vorhanden sind, als mongod auf der Festplatte speichern kann? Wird es eine Warnung geben oder scheitert sie einfach stillschweigend?

Gibt es eine Methode zur Überwachung der Schreiblast? Ich habe nur gefunden, db.serverStatus().writeBacksQueuedwas immer auf false gesetzt ist, wenn ich es aufrufe. Wie kann ich testen, wie viele Daten ich einfügen muss, um die Schreibwarteschlange zu füllen?

mongostatzeigt Schlösser an. Sollte ich mir darüber Sorgen machen?

insert  query update delete getmore command flushes mapped  vsize    res faults  locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
  *117     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:6.5%          0       0|0     0|0   124b     6k     2  SLV   09:58:10 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:0.8%          0       0|0     0|0   124b     6k     2  SLV   09:58:11 
  *111     *0     *0     *0       0     2|0       0  17.4g  35.3g  3.76g      0     .:4.2%          0       0|0     0|0   124b     6k     2  SLV   09:58:1

Muss ich mir Sorgen um Schreibsperren machen? Was passiert mit einer Einfügung während eines schreibgeschützten Zeitraums? Steht es in der Warteschlange und wird es später gespeichert?

Ich denke über ein einfaches Replikationssetup mit einem Master und einem Slave nach. Sperrt die anfängliche Synchronisierung oder ein Resynchronisierungsprozess die Datenbanken?

(Ich verwende Version 2.4.3.)

Update: Ich glaube, ich habe meine eigene Frage teilweise beantwortet. Ich habe es geschafft, mit einer einfachen while-Schleife, die ein kleines Testdokument einfügt, bis zu 12.000 Einfügungen pro Sekunde zu erzielen. Aber qr | qw zeigt immer noch, dass dort die Lese- und Schreibwarteschlange noch leer ist:

insert  query update delete getmore command flushes mapped  vsize    res faults       locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn repl       time 
 11234     *0      2     *0    1563     1|0       1  21.9g  44.3g  1.22g      0    testdb:58.9%          0       1|0     1|1   797k   980k     6  PRI   10:26:32 
 12768     *0      2     *0    1284     1|0       0  21.9g  44.3g  1.22g      0    testdb:58.0%          0       0|0     0|1   881k     1m     6  PRI   10:26:33 
 12839     *0      2     *0    1231     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.3%          0       0|0     0|1   883k     1m     6  PRI   10:26:34 
 12701     *0      2     *0     910     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   858k     1m     6  PRI   10:26:35 
 12241     *0      2     *0    1206     1|0       0  21.9g  44.3g  1.22g      0    testdb:56.7%          0       0|0     0|0   843k     1m     6  PRI   10:26:36 
 11581     *0      2     *0    1406     1|0       0  21.9g  44.3g  1.22g      0    testdb:61.8%          0       0|0     0|1   811k     1m     6  PRI   10:26:37 
  8719     *0      2     *0    1210     1|0       0  21.9g  44.3g  1.22g      0    testdb:43.8%          0       0|0     0|1   618k   762k     6  PRI   10:26:38 
 11429     *0      2     *0    1469     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.6%          0       0|0     0|1   804k   993k     6  PRI   10:26:39 
 12779     *0      2     *0    1092     1|0       0  21.9g  44.3g  1.22g      0    testdb:60.2%          0       1|0     0|1   872k     1m     6  PRI   10:26:40 
 12757     *0      2     *0     436     1|0       0  21.9g  44.3g  1.22g      0    testdb:59.7%          0       0|0     0|1   838k   432k     6  PRI   10:26:41 

Ich nehme an, dass dies bedeutet, dass Einfügungen alleine nicht viele Probleme verursachen: "Warteschlangen tendieren zu Spitzenwerten, wenn Sie viele Schreibvorgänge neben anderen schreibintensiven Operationen ausführen, wie z. B. großen Entfernungen." ( hier gefunden )

Meine offene Frage: Was passiert mit meinen Daten, wenn sich die Schreibwarteschlange langfristig erhöht?

lumbric
quelle

Antworten:

25

Sie haben hier einige Ihrer eigenen Fragen beantwortet, insbesondere haben Sie eine gute Vorstellung vom Aspekt der Schreibsperre in der Gleichung - mit 12.000 Einfügungen / Sek. Erreichen Sie ~ 60% Schreibsperre. Dies ist ein angemessenes Maß, um eine konsistente Leistung zu erzielen. Sie werden einige Konflikte bekommen und einige Operationen werden etwas langsamer sein, aber Sie möchten sich bei etwa 80% wirklich Sorgen machen - wie bei vielen Dingen, wenn Sie anfangen, mehr als 80% verfügbar zu sein Kapazität werden Sie häufiger Probleme schlagen.

In Bezug auf andere Engpässe und insbesondere die Geschwindigkeit, mit der Sie auf die Festplatte schreiben können, kann dies zu Problemen führen. Wenn Sie sich jedoch die relevanten Statistiken im Laufe der Zeit ansehen, würde ich empfehlen, MMS mit dem Munin-Node-Plugin zu installieren , um Hardware- und E / A- Statistiken zu erhalten Zusätzlich zu den MongoDB-Statistiken.

Wenn Sie das haben, sind die Metriken, die Sie im Auge behalten möchten:

  • Die durchschnittliche Flush-Zeit (so lange dauert die periodische Synchronisation von MongoDB auf die Festplatte)
  • Die IOStats auf der Registerkarte Hardware (insbesondere IOWait)
  • Seitenfehler (wenn Ihre Festplatte mit Schreibvorgängen beschäftigt ist und Sie Daten lesen müssen, konkurrieren sie um eine knappe Ressource)

Es ist dann ein bisschen kompliziert, aber hier ist eine Grundidee:

  • Wenn die durchschnittliche Spülzeit zu steigen beginnt, machen Sie sich Sorgen
  • Wenn es in den Bereich von mehreren Sekunden kommt, sind Sie wahrscheinlich an der Grenze (obwohl dies vom geschriebenen Datenvolumen und der Festplattengeschwindigkeit abhängt).
  • Wenn es sich 60 Sekunden nähert, wird sich die Leistung erheblich verschlechtern (die Spülung erfolgt alle 60 Sekunden, sodass sie sich im Wesentlichen in der Warteschlange befindet).
  • High IOWait wird auch die Leistung beeinträchtigen, insbesondere wenn Sie zu irgendeinem Zeitpunkt von der Festplatte lesen müssen
  • Daher ist es auch wichtig, die Fehlerstufen der Seiten zu betrachten

Das andere Teil dieses Puzzles, das wir noch nicht erwähnt haben, ist das Tagebuch. Dadurch bleiben die Daten auch auf der Festplatte erhalten (standardmäßig alle 100 ms). Wenn sich die Festplatte auf demselben Volume befindet, wird dies zur Auslastung der Festplatte hinzugefügt. Wenn Sie also eine hohe Festplattenauslastung feststellen, ist es eine gute Idee, das Journal auf eine andere Festplatte zu verschieben.

Es gibt keine wirklichen "magischen Zahlen", unter denen man bleiben kann. In den meisten Fällen handelt es sich um relative Zahlen. Ermitteln Sie also eine gute Basis für Ihren normalen Datenverkehr, überprüfen Sie, ob sich die Dinge im Aufwärtstrend befinden, und testen Sie die Auslastung, um zu sehen, welche Grenzen Sie haben und wann Fangen Sie an sich zu verschlechtern und Sie werden in guter Verfassung sein.

Nach all diesen Vorbemerkungen zu einigen Ihrer Fragen:

Was passiert, wenn mehr Einfügungen pro Sekunde vorhanden sind, als mongod auf der Festplatte speichern kann? Wird es eine Warnung geben oder scheitert sie einfach stillschweigend?

Wenn Sie anfangen, die Festplatte auf die oben beschriebenen Werte zu belasten, wird sich irgendwann alles verlangsamen (und dies hängt von Zeitüberschreitungen ab, wie leistungsfähig Ihre Hardware ist und wie Sie mit Ausnahmen umgehen), schlagen Ihre Schreibvorgänge fehl - wenn Wenn Sie eine neuere Version von Pymongo verwenden, verwenden Sie standardmäßig sichere Schreibvorgänge, die dann fehlschlagen. Wenn Sie etwas paranoider sein möchten, können Sie gelegentlich einen Schreibvorgang für j: true ausführen, der darauf wartet, OK zurückzugeben, bis der Schreibvorgang das Journal erreicht hat (dh auf der Festplatte). Dies ist natürlich langsamer als ein normaler sicherer Schreibvorgang, zeigt jedoch sofort Probleme mit der Festplattenkapazität an, und Sie können damit andere Vorgänge blockieren / in die Warteschlange stellen und im Wesentlichen als Drosselklappe fungieren, um zu verhindern, dass Ihre Datenbank aktiv wird überwältigt.

Ich denke über ein einfaches Replikationssetup mit einem Master und einem Slave nach. Sperrt die anfängliche Synchronisierung oder ein Resynchronisierungsprozess die Datenbanken?

Ich denke, ich habe zu Beginn das Sperren insgesamt behandelt, aber um dieses Teil genauer zu beantworten: Stellen Sie zunächst sicher, dass Sie ein Replikatset verwenden , nicht Master / Slave. Die Master / Slave-Implementierung ist veraltet und wird für die allgemeine Verwendung nicht empfohlen. Was die anfängliche Synchronisierung anbelangt, so wird die primäre Synchronisierung in Bezug auf Lesezugriffe, jedoch nicht in Bezug auf Schreibzugriffe belastet.

Was passiert mit meinen Daten, wenn sich die Schreibwarteschlange langfristig erhöht?

Wie Sie wahrscheinlich aus der obigen Erklärung ersehen können, hängt die Antwort stark davon ab, wie Sie Ihre Bewerbung verfassen, wie Sie sich für eine Bestätigung Ihrer Schreiben entscheiden und wie viel Kapazität Ihnen zur Verfügung steht. Sie können im Wesentlichen so sicher sein, wie Sie möchten, wenn Sie auf MongoDB auf Festplatte schreiben, aber es gibt einen Performance-Kompromiss, wie in der j:trueobigen Diskussion erwähnt.

Im Allgemeinen möchten Sie Ihren begrenzenden Faktor herausfinden - sei es Sperren, Plattengeschwindigkeit usw. - und dann die Pegel über die Zeit verfolgen und skalieren (Sharding) oder aufwärts (bessere Hardware), bevor Sie ein hartes Limit erreichen und Leistungsprobleme feststellen.

Eine letzte Sache db.serverStatus().writeBacksQueuedist tatsächlich eine Metrik, die in einer Sharded-Umgebung immer nur ungleich Null ist, und sie hat damit zu tun, dass sichergestellt wird, dass Schreibvorgänge in einen Chunk während einer Migration angemessen behandelt werden (vom Writeback-Listener gehandhabt ). Daher ist es hier im Wesentlichen ein roter Hering - nichts mit allgemeinem Schreibvolumen zu tun.

Adam C
quelle