Bit - loader

MongoDB para Big Data – replicación y sharding (III)

   Artículo | Big Data Fundations Bit - MongoDB para Big Data – replicación y sharding (III)
Ricardo Ahumada | 29/01/18

En el artículo anterior vimos los fundamentos de la configuración de MongoDB en modo sharding. Ahora la implementaremos técnicamente paso a paso

En este caso implementaremos en local la siguiente arquitectura que consistirá de:

  • Dos instancias replicadas de mongo
  • Una instancia replicada de servidor de configuración
  • Una instancia replicada de servidor de balanceo

Pasos de la configuración

1.- Creamos las carpetas de datos: cada una de las carpetas servirá para almacenar los datos de una instancia de Mongo replicada. Para ello abriremos un terminal de consola y en la ruta que deseemos, crearemos las carpetas.

mkdir p1_1 p1_2 p2_1 p2_2

 

2.- Carpetas de datos para los servidores de configuración: Asimismo necesitaremos activar instancias de mongo que sirvan como servidores de configuración, que mantendrán la información de la distribución de shards.

mkdir cgr1 cgr2

 

3.- Iniciamos los servidores de configuración en modo réplica

mongod –configsvr –replSet configrs –dbpath <ruta>\cgr1 –port 26050

mongod –configsvr –replSet configrs –dbpath <ruta>\cgr2 –port 26051

El parámetro “–configsvr” es el que indica que se trata de instancias de configuración. Asimismo el parámetro “–replSet configrs” indica que estas instancias estarán asociadas al conjunto de réplica con nombre “configrs”

 

Activamos la replicación

Para ello iniciamos una instancia de mongo en el puerto 26050

mongo -port 26050

Generamos una variable con la configuración de réplica:

> conf = {_id: “configrs”,

members: [ {_id:0, host:hostname()+”.local:26050″ },

{_id:1, host:hostname()+”.local:26051″ } ] };

Inicializamos el conjunto de réplica con la configuración:

> rs.initiate(conf);

 

4.- Los servidores de datos replicados: iniciamos los dos shards de servidores de datos replicados:

Primer conjunto: puertos 27100 y 27101

mongod –shardsvr –replSet p1 –dbpath <ruta>\p1_1 –port 27100

mongod –shardsvr –replSet p1 –dbpath <ruta>\p1_2 –port 27101

Segundo conjunto: puertos 27200 y 27201

mongod –shardsvr –replSet p2 –dbpath <ruta>\p2_1 –port 27200

mongod –shardsvr –replSet p2 –dbpath <ruta>\p2_2 –port 27201

 

Ahora activamos los conjuntos de réplica:

Para el primer conjunto

mongo –port 27100

> config = {_id: “p1″,

members: [ {_id:0, host:hostname()+”.local:27100″ },{_id:1, host:hostname()+”.local:27101″ } ] };

> rs.initiate(config);

> rs.status();

Para el segundo conjunto

mongo –port 27200

> config = {_id: “p2″,

members: [ {_id:0, host:hostname()+”.local:27200″ },{_id:1, host:hostname()+”.local:27201″ } ] };

> rs.initiate(config);

> rs.status();

 

5.- Creamos los procesos mongos: Los procesos mongos son los que harán de balanceadores para la distribución de las queries entre el conjunto que conforma el shard.

mongos –configdb configrs/127.0.0.1:26050,127.0.0.1:26051

mongos –configdb configrs/127.0.0.1:26050,127.0.0.1:26051 –port 26601

Le indicamos a mongos los servidores de configuración a través del parámetro “–configdb”; seguido del conjunto de réplica de los servidores de configuración “configrs” y, las direcciones y puertos de los mismos (26050 y 26051).

 

6.- Ponemos en marcha las particiones: Para ello conectamos en el cliente sin puerto (mongo):

mongo

Luego indicamos los maestros de cada conjunto de réplica de las instancias de datos:

> sh.addShard(“p1/”+hostname()+”.local:27100″);

> sh.addShard(“p2/”+hostname()+”.local:27200″);

Verificamos el estado:

> sh.status();

 

7.- Habilitando el sharding para una base de datos: Para ello crearemos una base de datos shipsdb y la habilitaremos para sharding.

> use shipsdb

> sh.enableSharding(“shipsdb”)

> sh.status()

 

8.- Usamos el sharding para una colección: para ello creamos una colección, y le indicamos que puede partir los valores usando la clave “_id”:

> sh.shardCollection(“shipsdb4.ships”,{_id:1},true)

> sh.status()

 

Insertamos valores:

> db.ships.insert({name:’USS Enterprise-D’,operator:’Starfleet’,type:’Explorer’,class:’Galaxy’,crew:750,codes:[10,11,12]});

> db.ships.insert({name:’USS Prometheus’,operator:’Starfleet’,class:’Prometheus’,crew:4,codes:[1,14,17]});

> db.ships.insert({name:’USS Defiant’,operator:’Starfleet’,class:’Defiant’,crew:50,codes:[10,17,19]});

> db.ships.insert({name:’IKS Buruk’,operator:’ Klingon Empire’,class:’Warship’,crew:40,codes:[100,110,120]});

> db.ships.insert({name:’IKS Somraw’,operator:’ Klingon Empire’,class:’Raptor’,crew:50,codes:[101,111,120]});

> db.ships.insert({name:’Scimitar’,operator:’Romulan Star Empire’,type:’Warbird’,class:’Warbird’,crew:25,codes:[201,211,220]});

> db.ships.insert({name:’Narada’,operator:’Romulan Star Empire’,type:’Warbird’,class:’Warbird’,crew:65,codes:[251,251,220]})

 

Hacemos lo mimos con otro conjunto de datos: Esto nos permitirá comprobar cómo se distribuyen los datos entre shards.

> use piedras

> sh.enableSharding(“piedras”)

> sh.shardCollection(“piedras4.minerales”,{_id:1},true)

> sh.status()

> db.minerales.insert({_id:”Calcita”, color:”Jaspeada”, brillo:”opaco”, dureza:3, textura:”Arcillosa”})

> db.minerales.insert({_id:”Plata”, color:”Plateado”,brillo:”Metálico”, dureza:2.7, textura:”Lisa”})

> db.minerales.insert({_id:”Cuarzo”, color:”Incoloro”,brillo:”Vítreo”, dureza:7, textura:”Lisa”})

> db.minerales.insert({_id:”Yeso”, color:”Jaspeado”, brillo:”Vítreo”,dureza:[1.5,2],textura:”Arcillosa”})

> db.minerales.insert({_id:”Halita”, color:”Blanco”,brillo:”Vítreo”, dureza:2.5, textura:”Granulosa”})

> db.minerales.insert({_id:”Grafito”,color:”Gris”,brillo:”Submetálico”, dureza:1, textura:”Granulosa”})

 

9.- Ahora podemos comprobar el número de chunks:

Debemos poder observar cómo se han distribuido los datos entre los dos shards.

Hay que tener en cuenta que la distribución se hace en función del tamaño de los chunks (64MB por defecto) y que ahora estamos insertando volúmenes muy pequeños de datos.

 

Probando el shard con volúmenes grandes de datos

Vamos a modificar el tamaño de los chunks y hacer inserciones de volúmnes grandes de datos.

Para ello aprovecharemos que MongoDB puede ejecutar scripts Javascript:

/* Enabling sharding for shardTestDB*/

 

1.- Habilitamos el sharding para una base de datos: En este caso para shardTestDB y para la colección users dentro de ella. Usaremos el campo username como índice para el sharding.

> sh.enableSharding(“shardTestDB”)

> use shardTestDB

> db.users.getIndexes()

> db.users.ensureIndex({username:1})

> sh.shardCollection(“shardTestDB.users”,{username:1})

 

2.- Cambiamos el tamaño del chunk: queremos observar una distribución simétrica entre los nodos del shard. Para ello forzaremos el tamaño del shard a 1MB.

> use config

> db.settings.find( { “_id” : “chunksize” } )

> db.settings.save( { “_id” : “chunksize”, value : 1 } )

> db.settings.find( { “_id” : “chunksize” } )

 

3.- Probamos que los datos se distribuyen aun cuando no se hayan balanceado inicialmente:

Detenemos el balanceador: para probar que los datos se distribuyen bien cuando este se reinicie

> sh.stopBalancer()

> sh.getBalancerState()

Insertamos los datos: usando javascript

> use shardTestDB2

> for (var i=0; i<100000; i++) { db.users.insert( { “username” : “user”+i, “created at” : new Date() } ); }

> sh.status( { verbose : 1 } )

Iniciamos el balanceador: y observamos cómo los datos se van distribuyendo entre shards con el comando sh.status()

> sh.startBalancer()

> sh.status( { verbose : 1 } )

Esperamos y verificamos nuevamente (hacer varias veces hasta que se estabilice)

 

4.- Probamos la inserción de datos con el balanceador activo:

Añadimos más datos y verificamos

> for (var i=100000; i<110000; i++) { db.users.insert( { “username” : “user”+i, “created at” : new Date() } ); }

> sh.status( { verbose : 1 } )

Verificamos que el sistema es capáz de encontrar un usuario concreto:

> db.users.find({‘username’:’user110000′});

 

Reflexiones finales

Tal como hemos observado en este artículo, el sharding es una técnica que nos puede ayudar a lograr los objetivos planteados para los sistemas Big Data.

Mongo nos ofrece una arquitectura que nos permitirá implementar esta técnica y usarla en conjunto con la replicación.

No obstante deberemos diseñar con cuidado la estrategia de sharding y elegir en consecuencia la clave de shard que usaremos, ya que tiene implicaciones tanto en el rendimiento, como en la disponibilidad.

Además en Mongo, una vez elegida la clave de shard, no se puede cambiar.

Una buen diseño de clave debe tomar en cuenta el “cómo se usarán los datos”, es decir las queries que se realizarán al sistema. Asimismo, deberemos visualizar su uso a futuro para determinar, por ejemplo, si usamos zonas.

En el siguiente artículo veremos la configuración técnica de Mongo en modo sharding.

 


Entradas relacionadas

Cursos relacionados
Nuestro sitio utiliza cookies para análisis. Si no estás seguro de ello, echa un vistazo a nuestra política de privacidad.