Inicio » MongoDB » Sharding in MongoDB

Sharding in MongoDB

Una de las razones centrales de la existencia de Mongo es utilizar de manera segura y rápida grandes cantidades de datos. La manera más rápida de hacer esto es dividiendo horizontalmente los datos por rangos de valor.(en vez de tener un único servidor con todos los valores de la colección algunos rangos de valores se distribuyen (sharded) entre diferentes servidores).

Componentes de un cluster sharded cluster :

Estas instancias especiales de  mongod almacenan los metadata del cluster. Y cachean la información para determinar que shard (pedazo) tiene que información. Se encargan de llevar el control del cluster.

Para desarrollo y test se puede funcionar con un único config server, pero en producción se debe utilizar siempre tres, para la redundancia y para la seguridad.

  • Dos o más shards. Cada shard consiste en una o más instancias de mongod  para almacenar los datos del shard.

Estas instancias mongod almacenan todos los datos actuales del cluster.

Cada shard es un cojunto de replicas y está conjunto consiste en múltiples instancias mongod. Pero todas estas instancias contiene la misma información. Los miembros de este conjunto proporcionan redundancia y alta disponibilidad para los datos de cada shard.

Se debe acceder a los datos a través de las instancias mongos. Si se conecta directamente al mongod solo se verá la fracción de datos que tenga. Los datos en cualquier shard serán aleatorios.

  • Una o más instancias  mongos

Las instancias mongos son el punto de interacción entre el cliente y el cluster mongo. Estas instancias permiten al usuario ver el cluster como un único servidor. Estas instancias utilizan una cantidad mínima de recursos y se  pueden ejecutar en los servidores de la aplicación sin impactar al rendimiento de la aplicación.

 

Comandos para la configuración de un cluster.

Esto es una configuración sencilla para un entorno de test, donde todos los servicios están levantados sobre la misma máquina. servidor de configuración, tres shards (donde se almacena los datos) y una instancia mongos que sirve para los clientes vean al cluster como único servidor.

mkdir  ~/dbs/shards1 ~/dbs/shards2 ~/dbs/shards3 ~/dbs/config

Al levantar el servidor de configuración, la instancia mongos y los tres shards no se devuelve el prompt al usuario, es como si se quedara colgado, es necesario abrir otra sesión.

mongod --configsvr --port 27000 --dbpath ~/dbs/config
mongos --configdb localhost:27000 --chunkSize 1 --port 27001
mongod --shardsvr --dbpath  ~/dbs/shards1 --port 27002
mongod --shardsvr --dbpath  ~/dbs/shards2 --port 27003
mongod --shardsvr --dbpath  ~/dbs/shards3 --port 27004

Es necesario fijarse que aquí me estoy conectando al puerto donde está el mongos, para añadir los shards.

mongo localhost:27001/admin
>db.runCommand({addshard : "localhost:27002", allowLocal : true})
>db.runCommand({addshard : "localhost:27003", allowLocal : true})
>db.runCommand({addshard : "localhost:27004", allowLocal : true})

Aquí establezco el campo por el que se va a realizar la división de datos. La división se va a realizar de forma aleatoria entre los tres shard y mongo lo va a hacer de forma automática.

>db.runCommand( { enablesharding : "test" } )
>db.runCommand( { shardcollection : "test.clients", key : {name : 1} } )

Configuraciones en producción:

Para configuraciones en producción es necesario configuraciones más robustas. Para que no haya un solo punto de fallo. Se necesitan:

Múltiples config servers

Múltiples mongos servers

Sets de replica por cada shrad.

Configurar  multiples config servers:

Simplemente levantamos tantos como nos haga falta:

$ mkdir -p ~/dbs/config1 ~/dbs/config2 ~/dbs/config3
$ ./mongod --dbpath ~/dbs/config1 --port 20001
$ ./mongod --dbpath ~/dbs/config2 --port 20002
$ ./mongod --dbpath ~/dbs/config3 --port 20003

Y cuando levantas la instancia mongos se tiene que conectar los tres servidores a ella.

$ ./mongos --configdb localhost:20001,localhost:20002,localhost:20003

Si uno de los servidores está caído, la información de configuración del cluster se queda solamente de lectura. Los clientes pueden leer y escribir, pero el rebalanceo (la distribución correcta de los datos entre los nodos) solo se producirá cuando todos los ficheros de configuración estén levantados. Sobre esto no he hecho pruebas.

Configurar múltiples mongos:

También pueden existir tantos procesos mongo como se quiera. La recomendación es levantar un proceso por cada servidor de aplicaciones. Cada servidor de aplicaciones habla con los mongos de manera local y si el servidor se cae, nadie necesitará utilizar ese instancia de mongo.

Set de réplica de cada shard:

En producción cada shard deberá estar compuesto por un set de réplica (tiene que ser un replica set no vale otra cosa), para que cuando se caiga una de ellos no se pierda el servicio, ya que la pérdida de un shard implica la que no se pueda consultar.

Replicas:

He probado a configurar un set de replicas compuesto de nodos y lo que he visto es que cuando uno de ellos se cae el otro se convierte en secondary y deja igualmente de dar servicio.

Creación del set de replicas:

Creamos los dos nodos.

mkdir ~/dbs/node1 ~/dbs/node2
mongod --dbpath ~/dbs/node1 --port 27005 --replSet prudataset/localhost:27005
mongod --dbpath ~/dbs/node2 --port 27006 --replSet prudataset/localhost:27005

Le dedicamos a uno de los nodos los componentes del set de replicas.

mongo localhost:27005/admin
MongoDB shell version: 1.5.3
connecting to localhost:10001/admin
type "help" for help
> db.runCommand({"replSetInitiate" : {
"_id" : "prudataset",
 "members" : [
    {
   "_id" : 0,
        "host" : "localhost:27005"
    },
    {
        "_id" : 2,
        "host" : "localhost:27006"
    }
 ]}})

Finalmente lo añadimos al shard cluster

mongo localhost:27001/admin
>db.runCommand({"addshard" : "prudataset/localhost:27005"})

Ya tenemos el set de replicas con al 27005 como primaria y la 27006 como secundario:

[root ~]# mongo localhost:27005/admin
MongoDB shell version: 2.2.1
connecting to: localhost:27005/admin
prudataset:PRIMARY> exit
bye
[root@rh53-10-3 ~]#  mongo localhost:27006/admin
MongoDB shell version: 2.2.1
connecting to: localhost:27006/admin
prudataset:SECONDARY> exit

Tiramos el nodo secundario y el 27005 que antes era primario se convierte en secundario, con lo que nuestras consultas al mongos y al conjunto de shards fallan

mongo localhost:27005/admin
MongoDB shell version: 2.2.1
connecting to: localhost:27005/admin
prudataset:SECONDARY> exit
mongo localhost:27001/admin
MongoDB shell version: 2.2.1
connecting to: localhost:27001/admin
mongos> db.printShardingStatus()
Mon Dec  3 05:05:34 uncaught exception: error {
        "$err" : "ReplicaSetMonitor no master found for set: prudataset",
        "code" : 10009
}

Por lo que visto esto se debe a que el set de replicas tiene que estar compuesto de tres nodos, porque en caso de caída se hace una votación para ver que nodo se queda como master y gana el que obtiene mayoría, en caso de un set de réplica de dos nodos, nunca ninguno obtendrá mayoría. Lo que he encontrado es un tipo de nodo que es árbitro no contiene datos y solo se utiliza para la votación, he hecho pruebas y en caso de caída del árbitro sigue funcionando.

Se añade un nodo más:

mongod --dbpath ~/dbs/node3 --port 27007 --replSet prudataset/localhost:27005,localhost:27006
rs.add("localhost:27007", true) –Con el true le decimos que es un árbitro.
Para ver la configuración
rs.status()

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s