lunes, 29 de noviembre de 2010

MongoDB: Conjuntos de réplica. Parte 3

Este post asume que sabes qué son los conjuntos de réplica y algo de la sintáxis básica.

En la parte 1, configuramos un conjunto de réplica desde cero, pero la vida real es más desordenado: puedes querer migrar servidores de desarrollo a producción, añadir nuevos esclavos, priorizar servidores, cambiar cosas en el momento (on the fly)... y ésto es lo que este post cubre.


Antes de empezar…

A los conjuntos de réplica no les gusta localhost. Son serviciales para secundarlos... más o menos, bastante... pero a menudo provoca discrepancias. Puedes evitar estas discrepancias usando en su lugar el nombre del servidor (hostname). En Linux, puedes buscar tu nombre de servidor ejecutando el comando:

$ hostname
wooster


De aquí en adelante, usaremos mi nombre de servidor en lugar de localhost.


Arrancar con datos

Esto es más o menos que arrancar sin datos, escepto que deberías hacer una copia de seguridad de tus datos antes de arrancar (deberías siempre hacer un backup siempre de tus datos antes de hacer travesuras con tu servidor de configuración).

Si en el pre-conjunto-réplica, arrancaste tu servidor con algo como:

$ ./mongod

...conviértelo en el primer miembro de tu conjunto de réplica, por lo que has de parar y arrancar de nuevo con la opción –replset:

$ ./mongod --replSet unicomplex/wooster:27017

Ahora, inicializa el conjunto con el único servidor:

> rs.initiate()
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}



Agregar esclavos

Deberías arrancar MongoDB siempre con esclavos, así que agreguemos alguno.

Arranca tu servidor con las opciones usuales, así como también como –replSet. Así, por ejemplo, podríamos hacer:

$ ./mongod --dbpath ~/dbs/slave1 --port 27018 --replSet unicomplex/wooster:27017

Ahora, agregamos este esclavo al conjunto de réplica. Asegurarse de que db está conectado a wooster:27017 (el servidor primario) y arrancar:

> rs.add("wooster:27018")
{"ok" : 1}


Repetir como sea necesario para agregar más esclavos.


Agregar un árbitro

Esto es muy similar a agregar un esclavo. Cuando arranques el árbitro, deberías darle la opción –oplogSize 1. De esta manera el árbitro no desperdiciará espacio.

$ ./mongod --dbpath ~/dbs/arbiter --port 27019 --replSet unicomplex/wooster:27017 --oplogSize 1

Ahora agregarlo al conjunto. Puedes especificar que este servidor es un árbitro pasando en un objeto un campo arbiterOnly a rs.add:

> rs.add({"host" : "wooster:27019", "arbiterOnly" : true})
{"ok" : 1}



Degradar un primario

Supongamos que nuestra compañía tiene disponibles los siguientes servidores:

1. Super máquina Gazillion dollar
2. Instancia EC2
3. iMac que encontramos en la calle

A través de un accidente del destino, el iMac se convierte en primario. Podemos forzarle a que se convierta en esclavo ejecutando el comando:

> imac = connect("imac.example.com/admin")
connecting to: imac.example.com/admin
admin
> imac.runCommand({"replSetStepDown" : 1})
{"ok" : 1}


Ahora el iMac será un esclavo.


Establecer prioridades

Podemos indicar que el iMac nunca sea un maestro (queremos usarlo sólo como backup). Puedes forzar ésto estableciendo su prioridad a cero. La más alta prioridad de un servidor es la que hará que se convierta en maestro si el actual maestro falla. Las únicas opciones son 0 (no puede ser maestro) o 1 (puede ser maestro), pero en el futuro serás capaz de tener una buena graduación de prioridades..

Así, cambiaremos la prioridad del iMac a 0. Para cambiar la configuración, conectemos al maestro y editemos su configuración:

> config = rs.conf()
{
"_id" : "unicomplex",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "prod.example.com:27017"
},
{
"_id" : 1,
"host" : "ec2.example.com:27017"
},
{
"_id" : 2,
"host" : "imac.example.com:27017"
}
]
}


Ahora, tenemos que hacer dos cosas: 1) establecer la prioridad del iMac a 0, y 2) actualizar la versión de la configuración. El nuevo número de versión es siempre el anterior más uno

> config.members[2].priority = 0
0
> config.version += 1
2


Finalmente, decimos al conjunto de réplica que tenemos una nueva configuración.

> use admin
switched to db admin
> db.runCommand({"replSetReconfig" : config})
{"ok" : 1}


Todos los cambios de configuración deben ocurrir en el maestro. Éstos se propagarán de éste a los esclavos. Ahora puedes "matar" cualquier servidor y el iMac nunca se convertirá en maestro.

Esta configuración es un poco melindrosa para hacer desde la consola. En el futuro, la gente probablemente utilice una GUI para configurar sus conjuntos y trastear con la configuración del servidor.


Artículo original: http://www.snailinaturtleneck.com/blog/2010/08/03/part-3-replica-sets-in-the-wild/