2012-07-11 12 views
10

Mientras convertía una colección en una colección con tope anoche, el tiempo optimo de mi secundario comenzó a retrasarse con respecto a la primaria. Avanzó lentamente, un par de segundos cada varios minutos, y finalmente se cayó de la ventana oplog de la primaria. Según las instrucciones here detuve mongod en el secundario, eliminé todos los archivos de datos y lo reinicié, aunque olvidé bloquear el primario de las escrituras. El secundario pasó por su fase de inicialización, que demoró un tiempo sólido, y finalmente volvió a funcionar, pero cuando inicié sesión, la replicación estaba aún más atrás.¿Por qué mi réplica de MongoDB sigue quedándose atrás?

Dado que esta es la nube, después de todo, creé una imagen de mi primaria (que se supone que copia todos los datos), aunque no pude ejecutar db.fsyncLock() en ese momento, porque estaba tomando algunas escribe La nueva imagen finaliza y lanzo un nuevo servidor basado en esa imagen, lo agrego a mi conjunto de réplicas, elimino el antiguo secundario y la vida es buena, ¿no? No del todo, la nueva secundaria se queda a una hora de retraso, y durante el transcurso del día (y esta noche) finalmente llega al punto en que está 14 horas atrás (aunque lo suficientemente extraño aún en la ventana oplog).

Doy el siguiente paso desde la "resincronización de una página obsoleta". Apague mongod en ambos servidores, gzip y copie mi carpeta de datos de primaria a secundaria, descomprímalos, active ambos, db.fsyncLock() mi principal. Lo que me sorprende es que incluso con THE MISMO DATOS, después de inicializar, mi secundaria dice que está 1 hora atrás. Lo vuelvo a agregar al conjunto de réplicas y alcanza rápidamente 5 minutos.

Todo bien, ¿verdad? No, flash forward, secundaria avanza lentamente, y ahora está 20 minutos atrás. Mongostat tiene una vinculación secundaria de 95+% bloqueado, iostat -xm 2 no muestra nada loco - la primaria actualmente está inactiva por no tomar escrituras, la secundaria definitivamente no está haciendo mucho (.04 wMB/segundo). No estoy seguro de si vale la pena mencionarlo, pero el principal actualmente se siente perro lento registro insensible en el caparazón de mongo, etc.

¿Qué ofrece, Mongo? ¿Por qué no puedes simplemente ponerte al día? ¿Qué estoy haciendo mal al intentar que mi secundaria se ponga al día?

EDITAR de cuestiones:

  • Versión: 2.0.4
  • Hardware: Ambos nodos son el mismo hardware, lo que puedo decir - 8 GB de RAM, CPU de cuatro núcleos. Supongo que es algo virtualizado.
  • Escribir tasa: varía. Como mencioné, anoche me estaba convirtiendo en una colección con tope, que desencadenó todo. De la noche a la mañana, hubo un proceso escribiendo alrededor de un par de cientos de documentos pequeños (~ 155 bytes cada uno) unas pocas veces por hora, por lo que estimé en máximo 100-200 kbytes/hora. Durante el día, el procesamiento fue más intenso, actualizando cientos de miles de documentos de 500 bytes y escribiendo un par de cientos de miles más. Todavía no se habla de enormes cantidades de datos. EDITAR encontrar alguna salida de iostat desde el día de hoy:
 
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 

que uno era particularmente a ráfagas a los 11 WMB/s, vio util% alcanzó el 34% con 7 WMB/s, y el 72% a las 52 RMB/s. Entonces no está saturado, pero definitivamente es una carga de trabajo de lectura pesada en la mañana. Sin embargo, es interesante que a pesar de tener obj. tamaño ~ 5GB, y ~ 1GB índices (ver a continuación), hay tanta actividad en el disco. ¿No debería estar todo eso en la RAM?

  • conjunto de trabajo: Todavía no han encontrado la metodología aceptada para el cálculo conjunto de trabajo, pero si ayuda:
 
    "collections" : 21, 
    "objects" : 15540092, 
    "avgObjSize" : 325.26198326238995, 
    "dataSize" : 5054601144, 
    "storageSize" : 5874327552, 
    "numExtents" : 132, 
    "indexes" : 43, 
    "indexSize" : 864366720, 
    "fileSize" : 10666115072, 
    "nsSizeMB" : 16, 
    "ok" : 1 

no puedo imaginar que eso es abrumadora 8 GB de RAM, aunque Podría estar equivocado.

  • algunas muestras recientes mongostat de secundaria:
 
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

intentado más cosas. Apagué el primario (ahora se llama A, el secundario será B), borré sus datos y descomprimí su instantánea (ahora hace un par de horas, pero en este punto, no estamos escribiendo nada nuevo). Comencé A con --fastsync, y todavía está como 45 segundos detrás del tiempo óptimo de B (ahora principal), que había estado saliendo alrededor de 02: 19: 52UTC. Finalmente, aproximadamente una hora más tarde, A se pone al día, por lo que llamo a rs.stepDown() en B. Instantáneamente, rs.status() me muestra que ambos servidores tienen un tiempo óptimo alrededor de las 04:08 UTC, pero B (ahora secundario) vuelve a estar rezagado por 17 segundos ... entonces ... ahora 30 segundos a 7 minutos ...

EDIT

unos pocos minutos después de tomar @ sugerencia y de matulef volver a crear índices en las cubiertas de mis colecciones, así como reiniciando el proceso mongod secundario, su tiempo optimo solo ha aumentado unos segundos. El% bloqueado secundario del mongostat sigue oscilando entre el 95% y el 104%, y curiosamente, el tamaño del res oscilaba bastante de 100M a 2GB y viceversa antes de establecerse alrededor de 1GB.

EDITAR (la noche siguiente)

Conclusión de la historia - @matulef estaba en el camino correcto, que debería haber sido más cuidadoso acerca de cómo convertir una colección replicada a una colección tapado. Lo que sigue es lo que sucedió, aunque no publicité esto como datos seguros: reconozco abiertamente que puedo haber perdido algunos datos en este proceso, por lo que YMMV.

La creación de índices para las colecciones limitadas en el primario (A) no se propagó al secundario (B), y A pasó a fallar (no intencionalmente). Una vez que B era primario, creé manualmente los índices en las colecciones limitadas, y la operación de resincronización para poner A en línea con B comenzó a moverse rápidamente. Desafortunadamente para mí, mis ventanas oplog ya no se alineaban, así que terminé teniendo que hacer una instantánea de datos de B a A. Una vez que reinicié mongo con el mismo conjunto de datos, A & B estaban contentos de nuevo, y la replicación ha estado de vuelta en sincronización desde entonces.

+0

es el secundario el mismo hardware que el primario? también qué versión de mongoDB es esto? –

+0

¿Cuál es la tasa de escrituras? ¿Cuánta RAM y qué mongos funcionan? – Kevin

+1

¿Tiene un índice _id para su colección con el tope? Por defecto, no se crea en colecciones limitadas, así que supongo que cuando hiciste un "convertToCapped" lo perdiste. Esta es una causa común (y fácil de solucionar) del retraso de replicación. Consulte la advertencia aquí: http://www.mongodb.org/display/DOCS/Capped+Collections – matulef

Respuesta

6

El problema aquí es que las colecciones limitadas no tienen un índice _id por defecto (y el comando "convertToCapped" en realidad cae todos los índices para esa colección). Esto es un problema porque los secundarios realizan actualizaciones aplicando operaciones del oplog, que se refieren a documentos por sus _ids. Si le falta un índice _id, cada actualización requiere una exploración completa de la tabla en los secundarios, lo que hace que se retrasen mucho.

La solución es crear un índice _id en la colección con el tope. Sin embargo, si crea el índice en el primario, pero sus secundarios ya están rezagados, no recibirán la operación de creación del índice lo suficientemente rápido. En cambio, la mejor manera de arreglar las cosas es primero arreglar cada secundario rezagado, uno por uno.Para cada uno, apáguelo y reinícielo en modo independiente (en un puerto diferente, sin la opción --replSet), genere el índice _id y vuélvalo a agregar al conjunto. Finalmente, una vez que los secundarios están arreglados, puede bajar el primario y repetir el proceso con él también.

Actualización: en mongoDB 2.0.xy versiones anteriores, las colecciones limitadas no tienen un índice _id por defecto. Sin embargo, el comportamiento predeterminado está programado para cambiar en mongoDB 2.2, por lo que las colecciones limitadas creadas en 2.2+ tendrán un índice _id creado automáticamente, al igual que con las colecciones no limitadas. Para las colecciones limitadas creadas antes de la versión 2.2, aún deberá crear manualmente un índice _id siguiendo los pasos descritos anteriormente, pero las nuevas colecciones no deberían sufrir los problemas antes mencionados.

Cuestiones relacionadas