2012-07-11 16 views
10

Beim Konvertieren einer Sammlung in eine Capped-Sammlung letzte Nacht begann der Optimalwert meiner Sekundärseite, hinter dem Primär zu liegen. Es ging langsam alle paar Minuten ein paar Sekunden vor und fiel schließlich aus dem Oplog-Fenster des Primärsystems. Nach den Anweisungen here stoppte ich Mongod auf der sekundären, löschte alle Datendateien und neu gestartet, obwohl ich vergessen, die primäre von Schreibgeschäften zu sperren. Secondary durchlief seine Initialisierungsphase, die eine ziemlich lange Zeit in Anspruch nahm, und war schließlich wieder im Geschäft, aber als ich mich anmeldete, war die Replikation noch weiter zurück.Warum fällt meine MongoDB-Replik immer hinterher?

Da dies die Wolke ist, habe ich schließlich ein Bild von meiner primären (die alle Daten kopieren soll) erstellt, obwohl ich db.fsyncLock() zu der Zeit nicht ausführen konnte, weil es einige dauerte schreibt. Das neue Bild wird fertiggestellt, und ich starte einen neuen Server basierend auf diesem Bild, lasse es zu meinem Replikat hinzufügen, entferne das alte sekundäre und das Leben ist gut, oder? Nicht ganz - der neue Zweitplatzierte liegt etwa eine Stunde hinterher und erreicht im Laufe des Tages (und heute Nacht) schließlich den Punkt, an dem er 14 Stunden zurückliegt (obwohl merkwürdigerweise immer noch im oplog-Fenster).

Ich mache den nächsten Schritt von der "Resyncing eine veraltete Mitgliedsseite". Shutdown mongod auf beiden Servern, gzip und kopieren Sie meinen Datenordner von primären zu sekundären, entpacken, feuern sie beide, db.fsyncLock() meine primäre. Was mich in den Bann zieht, ist, dass selbst nach den Initialization mit den gleichen Daten, mein sekundärer sagt, es ist 1 Stunde zurück. Ich füge es wieder in das Replikatset ein und es fängt schnell an, 5 Minuten zurück zu sein.

Alles gut, oder? Nein - vorwärts blitzen, sekundär schreitet langsam voran und ist jetzt 20 Minuten zurück. Monostat hat sekundär bei 95+ gesperrt%, iostat -xm 2 zeigt nichts Verrücktes - Primär ist derzeit im Leerlauf von nicht Schreibvorgänge, sekundär ist definitiv nicht viel (0,04 WMB/Sekunde). Nicht sicher, ob es erwähnenswert ist, aber primäre fühlt sich derzeit Hund langsam nicht reagierende Anmeldung in der Mongo Shell usw.

Was gibt, Mongo? Warum kannst du nicht einfach aufholen? Was mache ich falsch, wenn ich versuche, meinen Sekundanten zu erwischen?

EDIT Beantwortung von Fragen:

  • Version: 2.0.4
  • Hardware: Beiden Knoten sind die gleiche Hardware, in der Nähe, wie ich sagen kann - 8 GB RAM, Quad-Core-CPU. Ich nehme an, es ist etwas Virtualisiertes.
  • Schreibrate: variiert. Wie bereits erwähnt, habe ich letzte Nacht in eine Capded-Kollektion umgewandelt, die das Ganze ausgelöst hat. Über Nacht gab es einen Prozess, der ein paar Mal pro Stunde ein paar hundert kleine Dokumente (~ 155 Bytes) schrieb, also würde ich ungefähr 100-200kbytes/Stunde schätzen. Während des Tages war die Verarbeitung intensiver, es wurden Hunderttausende von 500-Byte-Dokumenten aktualisiert und ein paar Hunderttausend mehr geschrieben. Immer noch nicht über enorme Datenmengen. EDIT fand einige iostat Ausgabe von früher heute:
 
Device:   rrqm/s wrqm/s  r/s  w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util 
xvda    1.00 2564.50 243.50 282.50 8986.00 11388.00 77.47 11.32 21.46 2.36 37.93 0.50 26.50 

Dass man besonders bursty wurde auf 11 Wmb/s, sah util% 34% mit 7 Wmb/s geschlagen, und 72% bei 52 RMB/s. So nicht gesättigt, aber auf jeden Fall eine lese-schwere Arbeitslast am Morgen. Es ist interessant, dass trotz obj. Größe ~ 5GB und ~ 1GB Indizes (siehe unten), es gibt so viel Festplattenaktivität. Sollte das nicht alles im RAM sein?

  • Arbeitssatz: Ich habe noch nicht die akzeptierte Methode zur Berechnung des Arbeitssatzes gefunden, aber wenn es hilft:
 
    "collections" : 21, 
    "objects" : 15540092, 
    "avgObjSize" : 325.26198326238995, 
    "dataSize" : 5054601144, 
    "storageSize" : 5874327552, 
    "numExtents" : 132, 
    "indexes" : 43, 
    "indexSize" : 864366720, 
    "fileSize" : 10666115072, 
    "nsSizeMB" : 16, 
    "ok" : 1 

Ich kann mir nicht vorstellen, dass das ist überwältigend 8 GB RAM, obwohl Ich könnte falsch liegen.

  • einige neuere mongostat Proben von Sekundär:
 
insert query update delete getmore command flushes mapped vsize res faults locked % idx miss %  qr|qw ar|aw netIn netOut conn set repl  time 
    *0  *0  *0  *0  0  1|0  0 22.2g 44.9g 912m  0  99.2   0  0|0  0|1  2k 303b 151 mySet SEC 03:47:54 
    *0  *0  *0  *0  0  1|0  0 22.2g 44.9g 1.85g  0  101   0  0|0  0|1  3k 303b 151 mySet SEC 03:48:04 

EDIT

haben versucht, mehr Dinge. Ich schalte die primäre (jetzt A, sekundäre wird B) herunter, löschte ihre Daten und entpackte ihren Schnappschuss (jetzt ein paar Stunden alt, aber an dieser Stelle schreiben wir nichts Neues). Begann ein up mit --fastsync, und es ist immer noch wie 45 Sekunden hinter dem B (jetzt primären) optime, der bei ungefähr 02: 19: 52UTC herumgehangen hatte. Endlich, etwa eine Stunde später, holt A auf, also rufe ich rs.stepDown() auf B. Sofort zeigt mir rs.status() an, dass beide Server um 04:08 UTC Zeit haben, aber B (jetzt sekundär) ist wieder zurück von 17 Sekunden ... dann 30 Sekunden ... jetzt 7 Minuten ...

EDIT

wenig Minuten nach @ matulef Vorschlag zu nehmen und neu zu erstellen Indizes auf meinen verkappten Sammlungen, sowie den mongod-prozess des sekundärs wieder startend, hat sich seine optime nur um ein paar sekunden verlängert. Secondary Locked% von Mongostat schwebt immer noch zwischen 95-104%, und interessanterweise schwankt die Res-Größe ziemlich wild von 100M auf 2GB und wieder zurück, bevor sie sich auf 1GB beläuft.

EDIT (am nächsten Abend)

Fazit der Geschichte - @matulef auf dem richtigen Weg war, soll ich vorsichtiger gewesen, eine replizierte Sammlung zu einer verkappten Sammlung zu konvertieren. Was folgt ist, was passiert ist, obwohl ich dies nicht als datensicher annonciere - ich gebe frei zu, dass ich in diesem Prozess möglicherweise Daten verloren habe, also YMMV.

Das Erstellen der Indizes für die Capped-Sammlungen auf der Primärdatenbank (A) wurde nicht auf die Sekundärdatenbank (B) übertragen, und A ist fehlgeschlagen (nicht absichtlich). Sobald B primär war, habe ich die Indizes für die Capped-Sammlungen dort manuell erstellt, und die Resynchronisierungsoperation, um A in Einklang mit B zu bringen, begann sich schnell zu bewegen. Leider standen meine oplog-Fenster nicht mehr in einer Reihe, also musste ich die Daten von B nach A schnappen. Nachdem ich Mongo mit dem gleichen Datenset neu gestartet hatte, waren A & B wieder glücklich und die Replikation war wieder da seither synchronisieren.

+0

ist die sekundäre die gleiche Hardware-weise wie die primäre? auch welche Version von mongoDB ist das? –

+0

Wie hoch ist die Schreibgeschwindigkeit? Wie viel RAM und was ist Mongos? – Kevin

+1

Haben Sie einen _id-Index für Ihre Capped-Sammlung? Standardmäßig wird es nicht für Sammlungen mit Begrenzungslinien erstellt, daher vermute ich, dass Sie es verloren haben, als Sie "convertToCapped" ausgeführt haben. Dies ist eine häufige (und leicht zu behebende) Ursache für die Replikationsverzögerung. Siehe Warnung hier: http://www.mongodb.org/display/DOCS/Capped+Collections – matulef

Antwort

6

Das Problem hier ist, dass Capped-Sammlungen standardmäßig keinen _id-Index haben (und der "convertToCapped" -Befehl tatsächlich alle Indizes für diese Sammlung fallen lässt). Dies ist ein Problem, da die Secondaries Aktualisierungen durchführen, indem sie ops aus dem oplog anwenden, die sich auf Dokumente mit ihren _ids beziehen. Wenn Ihnen ein _id-Index fehlt, erfordert jedes Update einen vollständigen Tabellenscan für die Secondaries, was dazu führt, dass sie weit zurückbleiben.

Die Lösung besteht darin, einen _id-Index für die Capped-Sammlung zu erstellen. Wenn Sie jedoch den Index für die Primärdatenbank erstellen, die Sekundärdatenbank jedoch bereits zurückliegt, wird die Indexerstellungsoperation nicht schnell genug ausgeführt. Stattdessen ist der beste Weg, um Dinge zu beheben, zunächst jede nacheilende Sekundärseite nacheinander zu reparieren.Beenden Sie für jeden einzelnen das Programm und starten Sie es im eigenständigen Modus (an einem anderen Anschluss ohne die Option --replSet), erstellen Sie den _id-Index und fügen Sie ihn dann wieder in den Satz ein. Schließlich, wenn die Secondaries behoben sind, können Sie das Primary zurücktreten und den Prozess damit wiederholen.

Aktualisieren: In mongoDB 2.0.x und früher haben Capped-Sammlungen standardmäßig keinen _id-Index. Es ist jedoch geplant, das Standardverhalten in mongoDB 2.2 zu ändern, sodass in 2.2+ erstellte gedeckelte Sammlungen automatisch einen _id-Index erstellen, genau wie bei nicht gecappten Sammlungen. Für gecappte Sammlungen, die vor 2.2 erstellt wurden, müssen Sie einen _id-Index mithilfe der oben beschriebenen Schritte manuell erstellen. Neue Sammlungen sollten jedoch nicht unter den oben genannten Problemen leiden.