lunes, 29 de noviembre de 2010

MongoDB: Conjuntos de réplica. Parte 2

Los conjuntos de réplica son básicamente maestro-esclavo con failover automático.

La idea es: tienes un esclavo y uno o más esclavos. Si el maestro se cae, uno de los esclavos automáticamente se convertirá en el nuevo maestro. Los drivers de base de datos, siempre encontrarán al maestro, si el maestro que se está usando se cae, ellos (drivers) automáticamente entenderán quién es el nuevo maestro y envía las escrituras a dichos servidor. Esto es mucho más fácil de manejar (y más rápido) que manejar manualmente el fallo sobre un esclavo.

Así, tu tienes un pool de servidores con un primario (el maestro) y N secundarios (esclavos). Si el primario tiene un accidente y desaparece, los otros servidores mantendrán una elección para elegir un nuevo primario.


Elecciones

Un servidor tiene que obtener una mayoría del total de votos para ser elegido, no sólo una mayoría. Esto significa que, si tenemos 50 servidores y cada servidor tiene un voto (por defecto, los últimos post mostrará cómo cambiar el número de votos que un servidor obtiene), un servidor necesita al menos 26 votos para convertirse en primario. Si ninguno obtiene 26 votos, ninguno se convierte en primario. El conjunto puede todavía manejar lecturas, pero no escrituras (ya que no hay maestro).

Si un servidor obtiene 26 o más votos, éste se convertirá en primario. Todas las futuras escrituras serán direccionadas a éste, hasta que pierda una elección, estalle, etc.

El primario original es todavía parte del cojunto. Si lo levantas, éste se convertirá en un servidor secundario (hasta que obtenga nuevamente la mayoría de votos).

Una multitud de tres (de buena manera)

Una complicación con este sistema de votación es que tú no puedes tener sólo un maestro y un esclavo.

Si estableces sólo un maestro y un esclavo, el sistema tiene un total de 2 votos, así que un servidor necesita ambos botos para ser elegido maestro (1 no es mayoría). Si uno de los servidores se cae, el otro servidor sólo tiene un voto de 2, así que ésto lo convierte (o lo conserva) en un esclavo. Si la red está particionada, y repentinamente el maestro no tiene una mayoría de los votosos (sólo tiene su único voto), será degradado a un esclavo. El esclavo además no tiene una mayoría de los votos, po lo que permanecerá siendo esclavo (así que terminarás con dos esclavos hasta que los servidores se puedan alcanzarse el uno al otro de nuevo).

Esto es un desperdicio, aunque, tener dos servidores y ningún maestro levantado, los conjuntos de réplica tienen varias formas de evitar esta situación. Una de las más simples y más versátiles es usar un árbitro, un servidor especial que existe para resolver disputas. Éste no sirve ningún dato al mundo exterior, si no que es simplemente un votante (puede incluso estar en la misma máquina como otro servidor, siendo muy ligero). En la parte 1, el árbitro era localhost:27019.

Así, digamos que establecemos un maestro, un esclavo y un árbitro, cada un con un voto (total 3 votos). Entonces, si tenemos un maestro y un árbitro en un centro de datos y el esclavo en otro, si se produce una partición de red, el maestro todavía tendrá una mayoría de votos (maestro+árbitro). El esclavo tiene sólo 1 voto. Si el maestro falle y la red no se particiona, el árbitro puede votar por el esclavo, promocionándole como maestro.

Con esta configuración de tres servidores, obtenemos un failover sensible y robusto.

Lo próximo: configuración dinámica de tu conjunto de réplica. En la parte 1, confiramos todo completamente al empezar. En el mundo real querremos ser capaces de añadir servidores dinámicamente y cambiar la configuración.


Artículo original: http://www.snailinaturtleneck.com/blog/2010/08/02/replica-sets-part-2-what-are-replica-sets/

MongoDB: Conjuntos de réplica. Parte 1

Los próximos tres posts están dedicados a los conjuntos de réplica, una de las mejores características de MongoDB para asegurar la alta disponibilidad en un sistema de base de datos. Estos posts los escribió Kristina Chodorow, una de las desarrolladoras más importantes de MongoDB.

Este post muestra cómo hacer el "Hola, mundo" de los conjuntos de réplica. Voy a empezar con un post explicand qué es, pero la codificar es mucho más divertido que leer. Por ahora, todo lo que tienes que saber es que hay maestro-esclavo con failover (a prueba de fallos) automático.

Asegúrate de que tienes la versión 1.5.7 o superior de la base de datos (MongoDB) antes de probar el código que viene a continuación.

Paso 1: Elegir un nombre para tu conjunto

Esto es sólo organizacional, así que puedes elegir el que sea. Yo usaré "unicomplex" para mi ejemplo.

Nota: Kristina hace uso de su buen humor para la elección de un nombre. El nombre "que sea" es un artículo para dar un nombre a un bebé. Unicomplex se refiere a la saga de Startrek.


Paso 2: Crear los directorios de datos

Necesitamos un directorio de datos para cada servidor que vayamos a arrancar:

$ mkdir -p ~/dbs/borg1 ~/dbs/borg2 ~/dbs/arbiter


Paso 3: Arrancar los servidores

Arrancaremos nuestros tres servidores:

$ ./mongod --dbpath ~/dbs/borg1 --port 27017 --replSet unicomplex/
$ ./mongod --dbpath ~/dbs/borg2 --port 27018 --replSet unicomplex/
$ ./mongod --dbpath ~/dbs/arbiter --port 27019 --replSet unicomplex/



Paso 4: Inicializar el conjunto

Ahora tenemos que decirle al conjunto, "¡hey, existes!". Arranca la consola mongo y ejecuta:

MongoDB shell version: 1.5.7
connecting to: test
> rs.initiate({"_id" : "unicomplex", "members" : [
... {"_id" : 0, "host" : "localhost:27017"},
... {"_id" : 1, "host" : "localhost:27018"},
... {"_id" : 2, "host" : "localhost:27019", "arbiterOnly" : true}]})
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}


rs es una variable global que mantiene un racimo de funciones útiles para conjuntos de réplica.

El mensaje dice que estará online en aproximadamente un minuto, pero siempre han sido unos ~5 segundos para mi. Una vez que veas la siguiente línea en uno de los logs (trazas):

replSet PRIMARY

¡…tu conjunto de réplica está listo para funcionar!

Jugar con el conjunto

Uno de los servidores será el maestro (master), el otro es un esclavo (slave). Puedes entender cuál es cuál ejecutando el comando isMaster en la consola:

> db.isMaster()
{
"ismaster" : true,
"secondary" : false,
"hosts" : [
"localhost:27017",
"localhost:27018",
],
"arbiters" : [
"localhost:27019"
],
"ok" : 1
}


Si db no es primario, el servidor que está será listado en el campo "primary" (primario):

> db.isMaster()
{
"ismaster" : false,
"secondary" : true,
"hosts" : [
"localhost:27017",
"localhost:27018",
],
"arbiters" : [
"localhost:27019"
],
"primary" : "localhost:27018",
"ok" : 1
}


Ahora, prueba a "matar" el servidor primario. Espera un par de segundos y verás que el otro servidor (no-árbitro) será elegido primario.

Una vez que haya un nuevo primeraio, rearranca el mongod que acabas de "matar". Verás que se une a la refriega, aunque no se convierte en maestro (ya hay un maestro, así que no mecerá el barco). Después de unos pocos segundos, mata el maestro actual. Ahora, el antiguo maestro se convertirá en maestro de nuevo.

Es bastante divertido jugar con ésto, levantando y cayendo y mirando cómo el maestrazgo va atrás y adelante (o quizá yo me entretenga fácilmente).


Insertar y consultar datos

Por defecto, los esclavos están sólo como respaldo o backup, por lo que puedes usarlo para consultas (lecturas) si estableces el flag "slave ok". Conecta a cada uno de los servidores y establece este flag:

> db.getMongo().setSlaveOk()
> borg2 = connect("localhost:27018/test")
connecting to: localhost:27018/test
test
> borg2.getMongo().setSlaveOk()


Ahora puedes insertar, actualizar y eliminar datos en el maestro y leer los cambios en el esclavo.


Artículo original: http://www.snailinaturtleneck.com/blog/2010/07/30/replica-sets-part-1-master-slave-is-so-2009

MongoDB: Fragmentación y conjuntos de réplica ilustrados

Este post asume que conoces qué son los conjuntos de réplica y la fragmentación.

Paso 1: No usar fragmentación

En serio. Casi nadie lo necesita. Si estabas en el punto donde necesitabas particionar tu base de datos MySQL, probablemente tengas otras vías de hacerlo antes de que necesites particionar MongoDB (nos burlamos de los billones de filas).

Ejecuta MongoDB como un conjunto de réplica. Cuando necesites realmente capacidad extra, entonce, y sólo entonces, comienza la fragmentación. ¿Por qué?

1. Tienes que elegir una clave de fragmentación. Si conoces las características de tu sistema antes de elegir una clave de fragmentación, puedes ahorrarte a tí mismo un mundo de dolor.
2. La fragmentación añade complejidad.: tienes que mantener trazabilidad de más máquinas y procesos.
3. La optimización prematura es la raíz de todo mal. Si tu aplicación no se ejecuta rápido, ¿está tu CPI o tu red limitadas? ¿Tienes demasiados índices? ¿Demasiados pocos? ¿Están siendo golpeados por tus consultas? Verifica (al menos) todas estas causas primero.


Usar la fragmentación

Un fragmento está definido como uno o más servidores con un maestro. Asi, un fragmento podría ser un simple mongod (mala idea), una configuración maestro-esclavo (mejor idea), o un conjunto de ráplica (mejor idea).

Digamos que renemos tres fragmentos y cada uno de ellos es un conjunto de réplica. Para tres fragmentos, querrás un mínimo de 3 servidores (la regla general es: mínimo de N servidores para N fragmentos). Haremos también el mínimo en los conjuntos de réplica: un maestro, primario y árbitro para cada conjunto.

Las tazas son procesos MongoDB. Así, tenemos tres conjuntos de réplica:

“M” representa al “maestro” (master), “S” representa al “esclavo” (slave), y “A” representa el "árbitro" (arbiter). Tenemos también los servidores de configuración:

y procesos mongos:

Ahora, soporta estos procesos en servidores (las bandejas son servidores). Cada maestro necesita hacer mucho, así que cada primario toma su propio servidor.

Ahora ponemos también un esclavo y un árbitro en cada caja.

Observar cómo mezclamos las cosas: sin conjunto de réplica está alojado en un servidor simple, así que si un servidor se cae, el conjunto puede recuperarse en un servidor diferente y seguir funcionando.

Ahora podemos añadir tres servidores de configuración y dos procesos mongos. Los procesos mongos son puestos normalmente en el appserver, pero son muy ligeros, así que soportaremos un par de ellos aquí.

Un poco cargado, pero posible

En caso de emergencia...

Digamos que caemos una bandeja. CRASH! Con esta configuración, tus datos están a salvo (mientras estés usando w) y el cluster no pierde funcionalidad (en términos de lecturas y escrituras).

Los trozos no estarán disponibles para migrar (debido a que uno de los servidores de configuración está caído), así que un fragmento puede estar "hinchado" si el servidor de configuración está caído por mucho tiempo.

Las particiones de red y perder dos servidores son problemas grandes, así que deberías tener más de tres servidores si quieres gran disponibilidad.


Fuente original: http://www.snailinaturtleneck.com/blog/2010/08/09/sharding-and-replica-sets-illustrated/