Esta hoja muestra cómo crear un clúster (simulado con docker-compose
donde se mantienen dos replica sets (conjuntos de réplicas) y una colección (posts
) que se divide en cada una de esas dos replica sets. Al final se indica cómo escalar y añadir más hosts a las replica sets.
In [ ]:
!pip install --upgrade pymongo
In [ ]:
from pprint import pprint as pp
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib
%matplotlib inline
matplotlib.style.use('ggplot')
In [ ]:
%%bash
sudo apt-get update
sudo apt-get install -y mongodb-clients
Usaremos la librería pymongo
para python. La cargamos a continuación.
In [ ]:
%%bash
cat << END | mongo --host mongo_mongocfg1_1
rs.initiate(); // Iniciar el replica set de los servidores de configuración
sleep(1000);
rs.status()
END
In [ ]:
%%bash
cat <<END | mongo --host mongo_mongors1_1
rs.initiate(); // Inicio del RS
sleep(1000);
cfg = rs.conf();
cfg.members[0].host = "mongo_mongors1_1"; // Cambiar el host porque docker coge el hostname del contenedor
rs.reconfig(cfg); // Reconfigurar
//rs.add(host2/3) // Añadir posibles nuevos hosts añadidos al RS
rs.status()
END
In [ ]:
%%bash
cat <<END | mongo --host mongo_mongors2_1
rs.initiate();
sleep(1000);
cfg = rs.conf();
cfg.members[0].host = "mongo_mongors2_1";
rs.reconfig(cfg);
//rs.add(host2/3)
rs.status()
END
In [ ]:
import pymongo
from pymongo import MongoClient
La conexión se inicia con MongoClient
en el host
descrito en el fichero docker-compose.yml
(mongo
).
In [ ]:
client = MongoClient("mongo_mongors1_1",27017)
client
In [ ]:
client.database_names()
In [ ]:
%%bash
file=../Posts.csv
test -e $file || wget http://neuromancer.inf.um.es:8080/es.stackoverflow/`basename ${file}`.gz -O - 2>/dev/null | gunzip > $file
In [ ]:
db = client.stackoverflow
db = client['stackoverflow']
db
In [ ]:
posts = db.posts
posts
Importación de los ficheros CSV. Por ahora creamos una colección diferente para cada uno. Después estudiaremos cómo poder optimizar el acceso usando agregación.
In [ ]:
%%bash
mongoimport --db stackoverflow --collection posts --drop --type csv \
--headerline --host=mongo_mongors1_1 --file ../Posts.csv
In [ ]:
posts.count()
Creamos el índice por el que se creará el shard. Por defecto es de tipo ASCENDING
.
In [ ]:
posts.create_index('Id')
Añadimos al shard ambos ordenadores de ambos replica sets, y activamos el sharding en la tabla posts
.
In [ ]:
%%bash
cat <<END | mongo --host mongo_mongos_1
sh.addShard("mongors1/mongo_mongors1_1:27017");
sh.addShard("mongors2/mongo_mongors2_1:27017");
sh.enableSharding("stackoverflow");
sh.shardCollection('stackoverflow.posts', {'Id': 1})
END
In [ ]:
%%bash
cat <<END | mongo --host mongo_mongos_1
sh.status()
END
In [ ]:
post = posts.find_one()
post
In [ ]:
posts.find({"PostTypeId": 2}).explain()
Docker (compose) permite de forma muy sencilla hacer crecer y disminuir el número de servidores dedicados a un servicio. En este caso, podemos añadir más hosts virtuales a un replica set.
En el host donde se inició el docker-compose
, se puede aumentar el número de servicios de un replica set:
$ docker-compose up --scale mongors1=3
Esto crea dos servidores mongo
en el replica set mongors1
.
Finalmente, la idea es poder hacer esto en hosts físicos o virtualizados, usando de forma similar Docker Swarm o Kubernetes.