Tutorial MongoDB. Trabajando con conjuntos de réplicas

Empezamos el 2014 con una nueva entrega del tutorial de MongoDB. En el anterior artículo, pudimos ver cómo podemos crear un conjunto de réplicas y las distintas opciones que tenemos para configurarlo. En esta entrada, veremos como funciona dicho conjunto a la hora de realizar consultas o grabar nuevos documentos. También veremos como obtener información sobre el estado de la replicación de los elementos insertados, consultando la colección Oplog. Vamos al lío.

Nota: si no leíste el anterior artículo, recuerda que en el explico como configurar un conjunto de réplicas. Este conjunto, con la misma configuración es el que utilizaré a lo largo de esta entrada. Si ya tienes un conjunto creado, pero no tienes datos, puedes descargar los datos con los que he hecho los ejemplos desde aquí.

Consultas sobre un conjunto de réplicas

Como ya sabréis, MongoDB gestiona los conjuntos de réplicas siguiendo un modelo primario-secundario. Esto quiere decir que sólo un servidor podrá ser el principal, mientras que el resto de servidores serán considerados secundarios.

A la hora de realizar consultas, por defecto, las consultas se deben realizar sobre el servidor principal. Por ejemplo si nos conectamos al servidor principal (en este caso el que está escuchando en el puerto 27666)

MongoDB shell version: 2.4.8
connecting to: localhost:27666/test
rep1:PRIMARY>

Si nos fijamos en el mensaje que muestra la consola, vemos que dicho servidor aparece como PRIMARY, en el conjunto de réplicas rep1. En dicha consola podremos realizar consultas de forma normal sin ningún tipo de problema.

En cambio, si conectamos contra un servidor secundario, por ejemplo el que escucha por el puerto 27667, la consola mostrará un mensaje ligeramente distinto.

MongoDB shell version: 2.4.8
connecting to: localhost:27667/test
rep1:SECONDARY>

En este caso el servidor está catalogado por MongoDB como secundario. ¿Y qué pasa si intentamos hacer una consulta sobre este servidor?

rep1:SECONDARY> db.people.findOne()
Wed Jan 08 23:05:52.777 error: { "$err" : "not master and slaveOk=false", "code": 13435 } 
at src/mongo/shell/query.js:128
rep1:SECONDARY>

Como vemos en el error devuelto por la consola, la propiedad slaveOk es false, lo que quiere decir, que no hemos habilitado la opción que nos permite hacer consultas sobre un servidor secundario. Para habilitar la posibilidad de realizar consultas sobre un servidor secundario, tendremos que ejecutar la función slaveOk().

rep1:SECONDARY> rs.slaveOk()

Con ese comando, le estamos diciendo a MongoDB que sabemos que es un servidor secundario y que sabemos lo que estamos haciendo. Asumimos la responsabilidad. Y es que hay que tener en cuenta que al realizar consultas sobre un servidor secundario, los datos pueden no estar todavía replicados desde el servidor principal. Es decir, que podemos hacer consultas sobre datos no actualizados.

La posibilidad de realizar consultas sobre un servidor secundario, se utiliza principalmente para balancear la carga entre servidores. Si nuestra aplicación tiene muchas conexiones a la base de datos, nos puede interesar que algunas de las consultas se ejecuten sobre un servidor secundario. Pero tendremos que tener claro que estamos haciendo, ya que (y ya sé que me repito), los datos podrían no estar actualizados.

Inserciones y actualizaciones en un conjunto de réplicas

Las inserciones y actualizaciones son muy fáciles de entender. Solo se pueden modificar datos conectados desde el servidor principal. ¿Qué pasa si intentamos hacer una inserción desde un servidor secundario?

rep1:SECONDARY> db.people.insert({name:"Maria"})
**not master**

Ya veis que MongoDB se enfada. Nos dice que el servidor no es el principal y que no nos va a dejar realizar la inserción.

Endendiendo el Oplog

La colección Oplog es la que utiliza MongoDB para controlar las operaciones que hay que replicar a los servidores secundarios. Cada vez que hacemos una inserción en nuestra base de datos, esta se guarda en la colección Oplog que periódicamente es replicada a los servidores secundarios para que apliquen las mismas operaciones.

Para consultar esta colección tenemos varios comandos interesantes como getReplicationInfo()

rep1:PRIMARY> db.getReplicationInfo()
{
    "logSizeMB" : 8643.199609375,
    "usedMB" : 0.11,
    "timeDiff" : 2423165,
    "timeDiffHours" : 673.1,
    "tFirst" : "Wed Dec 11 2013 22:27:50 GMT+0100 (Hora estándar romance)",
    "tLast" : "Wed Jan 08 2014 23:33:55 GMT+0100 (Hora estándar romance)",
    "now" : "Wed Jan 08 2014 23:48:02 GMT+0100 (Hora estándar romance)"
}

Pero sin duda la manera más interesante de consultar los datos replicados es haciendo uso de la consola web que incluye MongoDB. Esta consola es accesible desde cualquier navegador consultando un puerto determinado.

Este puerto se establece sumando 1000 al puerto por el que esta escuchando el servicio mongod. En nuestro caso, podremos acceder a la consola web si en el navegador escribimos localhost:28666. Esta consola muestra diversos datos, pero para consultar el estado de los conjuntos de réplicas, deberemos ir a la sección Replica Set Status.

Importante: para tener todas las funciones de la consola web operativas, a la hora de lanzar el servidor deberemos incluir la opción –rest, que habilitará el acceso por API REST a algunas de las funciones de consulta de MongoDB.

En la sección Replica Set Status podremos ver información sobre los servidores que componen nuestra réplica. Si hacemos clic en alguno de los enlaces bajo la columna optime podremos ver las operaciones replicadas.

ts optime h op ns rest
Jan 08 23:33:55 52cdd253:1 53a92042bc903b70 i test.people v: 2 o: { _id: ObjectId(‘52cdd253ecea9b0557deb2bc’), personId: 0.0 }
Jan 08 23:33:55 52cdd253:2 47ee9c115ab50f74 i test.people v: 2 o: { _id: ObjectId('52cdd253ecea9b0557deb2bd’), personId: 1.0 }
Jan 08 23:33:55 52cdd253:3 4062a27b15156e51 i test.people v: 2 o: { _id: ObjectId('52cdd253ecea9b0557deb2be’), personId: 2.0 }
Jan 08 23:33:55 52cdd253:4 99b66c3b696eaae9 i test.people v: 2 o: { _id: ObjectId('52cdd253ecea9b0557deb2bf’), personId: 3.0 }
Jan 08 23:33:55 52cdd253:5 ad9a80592db8c942 i test.people v: 2 o: { _id: ObjectId('52cdd253ecea9b0557deb2c0’), personId: 4.0 }
Jan 08 23:33:55 52cdd253:6 b6b57f4bbe7ec98e i test.people v: 2 o: { _id: ObjectId('52cdd253ecea9b0557deb2c1’), personId: 5.0 }
Jan 08 23:33:55 52cdd253:7 ec8d576d28f35ec3 i test.people v: 2 o: { _id: ObjectId('52cdd253ecea9b0557deb2c2’), personId: 6.0 }

Conclusiones

Hoy hemos aprendido que podemos realizar consultas sobre un servidor secundario de MongoDB siempre que lo especifiquemos, pero que las inserciones y actualizaciones solo se pueden hacer sobre el servidor principal. También hemos aprendido que MongoDB gestiona una colección llamada Oplog dónde se guardan las operaciones realizadas. Esta colección es auditable, y nos servirá para detectar posible problemas de replicación. Problemas, que generaremos en la siguiente entrada.



Recuerda que puedes ver el índice del tutorial y acceder a todos los artículos de la serie desde aquí.



¿Quiéres que te avisemos cuando se publiquen nuevas entradas en el blog?

Suscríbete por correo electrónico o por RSS