Utilizar un servidor independiente, un servidor mongod único, es una manera
fácil de empezar, pero una forma peligrosa de funcionar en producción: ¿Y si
el servidor se bloquea o deja de estar disponible? La base de datos no estará
disponible al menos por un tiempo. Si hay problemas con el hardware, puede que
tengamos que mover los datos a otra máquina. En el peor de los casos, los
problemas con el disco o con la red podrían dejarnos con datos corruptos o
inaccesibles.
La replicación es una forma de mantener copias
idénticas de los datos en varios servidores y se recomienda para todas las
implementaciones de producción. La replicación mantiene la aplicación funcionando
y nuestros datos seguros, incluso si algo le sucede a uno o más de los
servidores.
Replicación en MongoDB |
Con MongoDB, configuramos la replicación
creando un conjunto de réplica. Un conjunto de réplica es un grupo de
servidores con un primario, el servidor atendiendo las solicitudes del cliente
y múltiples secundarios, servidores que guardan copias de los datos del
primario. Si el primario sufre algún daño, los secundarios pueden elegir a un
nuevo primario de entre ellos.
Si estamos utilizando la replicación y un
servidor se cae, todavía se puede acceder a los datos de los otros servidores
del conjunto. Si los datos de un servidor están dañados o inaccesibles, se puede
hacer una nueva copia de los datos desde otro de los miembros del conjunto.
Una Configuración de Conjunto de Réplica de Prueba en 1 Minuto.
Esta sección te ayudará a comenzar rápidamente configurando un conjunto de réplica de tres miembros en tu máquina local. Obviamente esta configuración no es adecuada para producción, pero es una buena manera de familiarizarse con la replicación y jugar con la configuración.
Una Configuración de Conjunto de Réplica de Prueba en 1 Minuto.
Esta sección te ayudará a comenzar rápidamente configurando un conjunto de réplica de tres miembros en tu máquina local. Obviamente esta configuración no es adecuada para producción, pero es una buena manera de familiarizarse con la replicación y jugar con la configuración.
Este
método de inicio rápido almacena los datos en /data/db, así que asegúrate de
que el directorio existe y que tu usuario pueda escribirlo antes de ejecutar
este código.
Inicia un shell de mongo con la opción --nodb,
que te permite iniciar un shell que no esté conectado a ningún mongod:
$ mongo --nodb
Crea un conjunto de replica ejecutando el
siguiente comando:
> replicaSet = new
ReplSetTest({"nodes" : 3})
Esto le dice al shell que cree un nuevo conjunto
de réplica con tres servidores: uno principal y dos secundarios. Sin embargo,
en realidad no inicia los servidores mongod hasta que ejecutes los dos comandos
siguientes:
> //
Inicia los tres procesos mongod
>
replicaSet.startSet()
>
> //
configura la replicación
>
replicaSet.initiate()
Ahora deberías tener tres procesos mongod
ejecutándose localmente en los puertos 31000, 31001 y 31002. Todos ellos
estarán volcando sus logs en el shell actual, lo que es muy ruidoso, así que
deja este shell a un lado y abre uno nuevo.
En el segundo shell, conéctate al mongodb que
se ejecuta en el puerto 31000:
>
conn1 = new Mongo("localhost:31000")
connection
to localhost:31000
testReplSet:PRIMARY>
testReplSet:PRIMARY>
primaryDB = conn1.getDB("test")
test
Observa que, cuando te conectas a un miembro
de conjunto de réplica, el indicador cambia a testReplSet:PRIMARY>. "PRIMARY"
es el estado del miembro y "testReplSet" es un identificador para
este conjunto. Aprenderás a elegir tu propio identificador más tarde; TestReplSet
es el nombre predeterminado que ReplSetTest utiliza.
Por legibilidad, los ejemplos de ahora en
adelante simplemente usarán el símbolo > para el indicador de entrada en
lugar de testReplSet:PRIMARY>.
Utiliza tu conexión al primario para ejecutar
el comando isMaster. Esto te mostrará
el estado del conjunto:
> primaryDB.isMaster()
{
"setName" : "testReplSet",
"ismaster" : true,
"secondary"
: false,
"hosts" : [
"wooster:31000",
"wooster:31002",
"wooster:31001"
],
"primary" : "wooster:31000",
"me" : "wooster:31000",
"maxBsonObjectSize"
: 16777216,
"localTime"
: ISODate("2012-09-28T15:48:11.025Z"),
"ok" : 1
}
Hay un montón de campos en la salida de isMaster, pero los más importantes indican que se puede ver que
este nodo es primario (el campo "ismaster":true) y que hay una lista
de hosts en el conjunto.
Si este servidor dice "ismaster":false,
está bien. Observa el campo "primary"
para ver qué nodo es primario y luego repite los pasos de conexión anteriores
para ese host / puerto.
Ahora que estás conectado al primario, vamos a intentar hacer algunas
escrituras y veamos qué sucede. Primero, inserta 1.000 documentos:
> for (i=0; i<1000; i++) { primaryDB.coll.insert({count: i}) }
>
> // nos aseguramos que están los documentos
> primaryDB.coll.count()
1000
Ahora comprueba uno de los secundarios y verifica que tengan una copia de
todos estos documentos. Conéctate a cualquiera de los secundarios:
> conn2 = new Mongo("localhost:31001")
connection to
localhost:31001
> secondaryDB = conn2.getDB("test")
test
Los secundarios pueden retrasarse con respecto al primario y no tener las
escrituras más actuales, por lo que los secundarios rechazarán las solicitudes
de lectura por defecto para evitar que las aplicaciones lean accidentalmente
datos obsoletos. Por lo tanto, si intentas consultar un secundario, obtendrás
un error indicando que no es primario:
> secondaryDB.coll.find()
error: { "$err" : "not master and
slaveok=false", "code" : 13435 }
Esto se hace para proteger la aplicación de conectarse accidentalmente a
un secundario y leer datos obsoletos. Para permitir consultas en el secundario,
establecemos un indicador "Estoy bien con la lectura de secundarios",
del siguiente modo:
> conn2.setSlaveOk()
Observa que slaveOk se
establece en la conexión (conn2), no
en la base de datos (secondaryDB).
Ahora ya estás listo para leer de este miembro. Ejecuta la consulta como
de costumbre:
> secondaryDB.coll.find()
{ "_id" : ObjectId("5037cac65f3257931833902b"), "count" : 0 }
{ "_id" : ObjectId("5037cac65f3257931833902c"), "count" : 1 }
{ "_id" : ObjectId("5037cac65f3257931833902d"), "count" : 2 }
...
{ "_id" : ObjectId("5037cac65f3257931833903c"), "count" : 17 }
{ "_id" : ObjectId("5037cac65f3257931833903d"), "count" : 18 }
{ "_id" : ObjectId("5037cac65f3257931833903e"), "count" : 19 }
Type "it" for more
>
> secondaryDB.coll.count()
1000
Se puede ver que todos los documentos están
ahí.
Ahora, intenta escribir a un secundario:
> secondaryDB.coll.insert({"count" : 1001})
> secondaryDB.runCommand({"getLastError"
: 1})
{
"err" : "not
master",
"code" : 10058,
"n" : 0,
"lastOp" : Timestamp(0, 0),
"connectionId" : 5,
"ok" : 1
}
Puedes ver que el secundario no acepta la escritura. El secundario
realizará solamente las escrituras que consiga a través de la replicación, no procedente
de clientes.
Hay otra característica interesante que debes probar: la recuperación
automática. Si el primario se cae, uno de los secundarios será elegido primario
de forma automática. Para probar esto, para el primario:
> primaryDB.adminCommand({"shutdown" : 1})
Ejecutar isMaster en el
secundario para ver quién se ha convertido en el nuevo primario:
> secondaryDB.isMaster()
Debe ser algo como esto:
{
"setName" : "testReplSet",
"ismaster" : true,
"secondary"
: false,
"hosts" : [
"wooster:31001",
"wooster:31000",
"wooster:31002"
],
"primary" : "wooster:31001",
"me" : "wooster:31001",
"maxBsonObjectSize"
: 16777216,
"localTime"
: ISODate("2012-09-28T16:52:07.975Z"),
"ok" : 1
}
Nuestro principal puede ser el otro servidor; Cualquiera de los
secundarios que se diera cuenta primero que el primario estaba caído será
elegido. Ahora puedes enviar escrituras al nuevo primario.
IsMaster es un comando muy
antiguo, precediendo a los conjuntos de réplicas, cuando MongoDB sólo soportaba
la replicación maestro-esclavo. Por lo tanto, no utiliza la terminología de
conjunto de réplica de forma coherente: todavía llama al primario un
"maestro". Generalmente se puede pensar en "maestro" como
equivalente a "primario" y "esclavo" como equivalente a
"secundario".
Cuando hayas terminado de trabajar con el conjunto, para los servidores
del primer shell. Este shell estará lleno de salida de los logs de los miembros
del conjunto, así que presiona Enter varias veces para volver a un indicador de
entrada (prompt). Para apagar el conjunto, ejecuta:
> replicaSet.stopSet()
¡Enhorabuena! Acabas de configurar, utilizar y desmantelar la
replicación.
Hay algunos conceptos clave a tener en cuenta:
- Los clientes pueden enviar a un primario todas las mismas operaciones que podrían enviar a un servidor autónomo (lecturas, escrituras, comandos, compilaciones de índices, etc.).
- Los clientes no pueden escribir en secundarios.
- Los clientes, por defecto, no pueden leer de secundarios. Al establecer explícitamente una configuración del tipo "Sé que estoy leyendo de un secundario", los clientes podrán leer de secundarios.
0 comentarios:
Publicar un comentario
Gracias por participar en esta página.