Creación de un Clúster Sharded en MongoDB
En el post de hoy os voy a explicar cómo crear un clúster sharded en MongoDB. Con este clúster conseguiremos obtener una mejora del rendimiento, una mejora del tiempo de lecturas y escrituras y un añadido al clúster de alta disponibilidad.
1. Configuración del Clúster
Para este caso, utilizaremos tres máquinas virtuales con Windows en Azure con servicio de DNS instalada en una de ellas. La arquitectura empleada es la siguiente:
Una vez tengamos instalado la versión de MongoDB que vayamos a utilizar junto con el programa de Compass, también instalaremos una herramienta externa que nos proporcionará seguridad con un key file, en este caso se ha utilizado OpenSSL.
Un key file sirve para autentificar la conexión entre servidores. Así que crearemos un fichero clave con los siguientes comandos:
cd C:\OpenSSL\bin
(Este comando sirve para ir al path que has elegido para almacenar los ficheros de OpenSSL)
set OPENSSL_CONF=C:\OpenSSL\bin\openssl.cnf
(Este comando sirve para que la configuración del OpenSSL sea igual que la del archivo openssl.cnf)
openssl rand -base64 756 > mongodb.key
(Y por último, le pedimos al programa openssl que nos cree una key totalmente aleatoria con el nombre mongodb.key)
Nos habrá creado el fichero en el path que hemos indicado anteriormente. Primeramente, moveremos dicho archivo a la ruta dónde están los archivos de MongoDB. Una vez movido lo deberemos de copiar en todos los servidores, para tener todos el mismo key file en la misma ubicación.
2. Configuración de la Replica-set de los dos Config Server
Ahora vamos a configurar la replica-set de los Config Server.
Antes que nada, crearemos una carpeta llamada, por ejemplo, Sharding. Dentro de ésta, crearemos dos nuevas llamadas DATA y LOG. Y siempre que creemos una carpeta dónde se almacenan únicamente los logs también crearemos un archivo .log.
Al ubicarnos de nuevo en la carpeta Sharding, crearemos el archivo .cfg. Este tipo de fichero indica a MongoDB que es un archivo de configuración. En él deberemos poner las características que queremos que tenga nuestra instancia.
La primera vez que lo editemos no habrá nada, pero cuando instalamos MongoDB hay un archivo que viene por defecto con todas las opciones posibles y por lo tanto con una plantilla. Por supuesto, el archivo deberá estar en la ubicación de instalación.
Al tratarse de una plantilla, copiaremos el interior del archivo y lo pegaremos en nuestro archivo .cfg que hemos creado anteriormente. En su interior nos encontraremos esto:
Como podemos observar, tenemos la capacidad de decidir dónde se almacenarán los datos y el log. También podemos elegir el puerto, incrementar la seguridad con el keyfile, las opciones que creamos oportunas en la replica y el sharding, y por último, nos ofrece unas opciones que únicamente están disponibles si obtienes la versión Enterprise. La versión empleada para esta demostración es Community Server 5.0.12.
Una vez modificado todo como queremos nos deberá de quedar una configuración similar a la siguiente:
Una best practice en esta configuración es proporcionar más seguridad con el key file, ya que no lo exige MongoDB para crear la instancia. Otra best practice es indicar, a parte de la IP, el nombre del servidor, porque si por algun casual cambiamos la IP de nuestra máquina, el servicio se pararía.
3. Validación de la Configuración
Ahora vamos a validar si la configuración es correcta creando el servicio con los siguientes pasos:
mongod --config "C:\Database\Sharding\cfgsrv.cfg" --install --serviceName
Mongocfgsrv --serviceDisplayName "MongoDB Config Server"
En este comando, se solicita la nueva instancia MongoDB con la configuración que está en el archivo del path propuesto, y que a parte, nos instale un nuevo servicio llamado Mongocfgsrv pero que nos lo muestre como MongoDB Config Server.
Antes que nada, el servicio estará parado. Será necesario levantar dicho servicio y ya empezará siempre cuando el servidor esté conectado gracias a la opción Automática. Aquí el resultado:
Si por algún casual al levantar el servicio nos sale una alerta así:
Significa que no hemos podido iniciar el servicio. Esto es síntoma de que el fichero tiene algún error. (Es posible que sea una tabulación)
Este proceso deberemos hacerlo en los otros dos servidores.
En el archivo de configuración, al ser diferentes servidores, preferiblemente pondremos el mismo puerto. Pero cuando pongamos la IP y el nombre del servidor lo deberemos de cambiar a la que se le haya otorgado al propio servidor.
Muestro la configuración del servidor W-10-2 para tener un ejemplo de ello:
4. Iniciamos el Grupo Replica-Set
Una vez hayamos realizado toda la configuración en los servidores restantes, vamos a iniciar el grupo replica-set. Primeramente nos conectaremos desde un CMD a la instancia creada: mongo localhost:27127. Este comando nos conecta a la instancia nueva porque le indicamos el puerto que hemos configurado en el archivo anterior.
Una vez nos dé la bienvenida a la instancia, crearemos definitivamente el grupo replica- set con el comando empleado en la imagen:
Observamos que con este comando le indicamos el nombre del replica-set que ya habíamos creado en los archivos. También le señalamos que este grupo replica-set es de configuración. Y, por último, los miembros que se juntan en el grupo con un identificador único.
También se puede ver que aparte de decir que lo hemos creado correctamente, ya se nos ha conectado a un miembro de éste.
5. Creación de Shards
A continuación vamos a crear los Shards.
Como siempre creamos las carpetas necesarias y los archivos necesarios para crear una nueva instancia en MongoDB.
En este caso se ha creado una carpeta llamada Shard y dentro de ésta se crea la carpeta de Data y Log con su respectivo archivo .log. y el fichero de configuración de la instancia. En los Shards, se distribuyen los roles en: Primario, Secundario y Árbitro.
Una vez más, copiamos la plantilla y la modificamos. Es muy parecida al archivo del servidor de configuración, pero con unos cambios.
Hay que especificar las nuevas rutas de DATA y LOG. También se requiere poner un nuevo puerto no utilizado anteriormente, indicar un nuevo nombre de grupo replica-set y cambiar el rol del clúster a shardsvr.
Ya sólo faltaría crear el servicio de la nueva instancia. Volveremos a abrir el cmd, nos ubicaremos dónde hayamos guardado la instalación de MongoDB y pondremos el comando correspondiente a la creación del servicio.
mongod --config "C:\Database\Sharding\Shard\shardpri.cfg" --install --serviceName Mongoshardpri --serviceDisplayName "MongoDB Shard Primary"
Este comando se cambiará dependiendo en el servidor que estemos, por ejemplo, si estamos en el secundario no queremos poner en el parámetro serviceDisplayName “MongoDB Shard Primary” si no que pondremos “MongoDB Shard Secondary”.
Abriremos el programa Servicios y en el nuevo servicio creado con un click derecho elegiremos la opción de iniciarlo. Sabemos que si nos salta una alerta deberemos revisar el archivo .cfg e intentarlo de nuevo.
Una vez hayamos creado las instancias en los demás servidores crearemos el shard en MongoDB. El procedimiento es ir a la ubicación dónde esté la instalación y conectarnos a la nueva instancia.
Una vez dentro crearemos nuestro replica-set dentro de los shards con el siguiente comando:
rs.initiate( { _id:"rsShard", members: [ {_id : 0, host : "W-10-1:27227", priority : 20}, {_id: 1, host : "W-10-2:27227", priority : 10}, {_id : 2, host : "W-10-3:27227", arbiterOnly : true} ] } )
Si nos fijamos bien, esta vez, vemos que aparte de no estar la opción de cfgsvr: true, se ha añadido la prioridad del servidor Primario y Secundario. Y también se ha añadido la opción de arbiterOnly:true para el servidor árbitro.
Para crear el segundo Shard deberemos proceder exactamente igual, pero teniendo en cuenta los cambios de los parámetros dentro del fichero .cfg de cada uno.
El siguiente paso consiste en crear el Router que su función es repartir la carga y escoger la ruta más rápida para la consulta deseada, aparte de proveer una interfaz entre la aplicación del cliente y el clúster.
En esta instancia crearemos los mismos archivos y carpetas menos la de DATA, ya que el router no puede obtener datos. Su objetivo es reducir la latencia y decide en que servidor encuentra los datos de la consulta pedida.
En este fichero de configuración no habrá parámetros que hagan referencia a la carpeta DATA ni habrá que especificar el nombre de replica-set. Y en el sharding, deberemos indicarle el grupo replica set y los miembros de los servidores de configuración, es decir, el primer replica set que hemos creado.
Es recomendable señalar los nombres de los servidores en vez de las IPs, recordamos que es una Best Practice.
El archivo quedaría tal que así:
6. Creación del Servicio Router
El siguiente paso es la creación del servicio del router, esta vez, en vez de hacerlo con la aplicación mongod la haremos con la aplicación mongos. Esto es debido a que la opción mongod no soporta una instancia sin Data, pero mongod sí. Aun así, iremos a la ubicación de instalación.
mongos --config "C:\Database\Sharding\Router\routercfg.cfg" --install --serviceName MongoRouter --serviceDisplayName "MongoDB Router"
Una vez ejecutado el comando, abriremos la pestaña de servicios y levantaremos el nuevo servicio.
Por último, nos conectaremos a la instancia del router.
Una vez dentro, crearemos un administrador con todos los permisos posibles, coloquialmente se conoce como SuperAdmin.
En primer lugar, deberemos otorgar permisos de la base de datos admin al usuario admin y acto seguido lo crearemos con todos los permisos posibles.
admin = db.getSiblingDB("admin") admin.createUser({user: "admin", pwd: "Password1",roles: [ { role: "userAdminAnyDatabase", db: "admin" }, { role: "clusterAdmin", db: "admin" }, { role: "readAnyDatabase", db: "admin" }, { role: "readWriteAnyDatabase", db: "admin" }, { role: "userAdminAnyDatabase", db: "admin" } ]})
A partir de que se crea el primer usuario la instancia nos requerirá registrarnos para efectuar cualquier opción. Así que vamos a autenticarnos:
Una vez hayamos ingresado las credenciales necesarias añadiremos los dos shards creados anteriormente, con el siguiente comando:
Empezaremos con el primer shard. Y a continuación añadiremos el segundo.
Como hemos visto sólo registrando los dos primarios ya estarán añadidos todos los demás nodos.
Desde el programa Compass nos conectamos al primer shard. Como no hay ningún usuario creado, nos conectaremos desde localhost y el puerto elegido en el siguiente formato
Como vemos en la parte inferior hay una línea de comandos.
Desde ese portal de mongosh, vamos a crear el SuperAdmin en la replica-set rsShard. No hay ningún cambio en este comando comparado con el realizado anteriormente:
Crearemos una nueva base de datos. Para ello iremos a la pestaña Databases y en verde hay una cajetilla donde haremos click para crear una base de datos.
Nos saldrá esta ventana dónde elegiremos el nombre de nuestra base de datos y de su colección.
Dentro de la base de datos, Examples en este caso, veremos todas las colecciones que tenemos:
Como sólo está la que hemos creado anteriormente, entramos en dicha colección e importaremos datos dentro de ella.
Esto es una función del programa database tools pero también se puede hacer desde aquí. Mucho más cómodo.
Una vez hayamos hecho click en Import Data nos redirigirá a esta pestaña:
Desde aquí elegiremos el tipo de archivo y seleccionaremos el archivo que tengamos descargados.
El documento que voy a tener de ejemplo es un archivo JSON que ofrece MongoDB de ejemplo.
Cuando la importación haya concluido podremos ver todos los datos que hay en la colección:
Ahora vamos a habilitar el Sharding en esta base de datos. Esto no indica que todas las colecciones que tengamos dentro de Examples vayan a fragmentarse.
Desde la instancia de mongos, es decir, la del router, lanzaremos el comando que necesario para llevar a cabo esta acción:
El siguiente paso es crear un índice antes de fragmentar la colección. Si no hacemos esto, nos impide realizar la fragmentación deseada.
Se debe tener en cuenta que, si la colección no tiene datos, se crea el índice automáticamente al fragmentar la colección.
Para crear el índice deberemos lanzar el comando que hay a continuación.
Vemos el campo por el que hemos creado el índice.
Ahora nos conectamos a la base de datos Examples
Y hacemos la fragmentación de la colección Prueba con el siguiente comando:
El parámetro _id es el campo por el que se organizará el indice y hashed es un tipo de fragmentación que proporciona una distribución de datos más uniforme en todo el clúster fragmentado.
Una vez finalizado este paso ya tendremos en nuestros servidores un clúster fragmentado con MongoDB.
Si quieres que te ayudemos a mejorar el rendimiento de tus servidores de BBDD, consulta nuestro servicio de SQL Server Health Check.
Data engineer with experience in SQL Server and MongoDB. Certified as a database administrator and data modeler in MongoDB, I specialize in designing and managing efficient and secure environments for database applications.