MongoDB es una base de datos NoSQL que utiliza documentos tipo JSON con esquemas dinámicos. Cuando se trabaja con bases de datos, siempre es bueno tener un plan de contingencia por si falla uno de tus servidores de bases de datos. Además, puedes reducir las posibilidades de que eso ocurra aprovechando una ingeniosa herramienta de gestión para tu sitio de WordPress.

Por eso es útil tener muchas copias de tus datos. También reduce las latencias de lectura. Al mismo tiempo, puede mejorar la escalabilidad y disponibilidad de la base de datos. Aquí es donde entra en juego la replicación. Se define como la práctica de sincronizar datos entre varias bases de datos.

En este artículo, nos sumergiremos en los diversos aspectos destacados de la replicación de MongoDB, como sus características y su mecanismo, por nombrar algunos.

¿Qué es la Replicación en MongoDB?

En MongoDB, los conjuntos de réplica realizan la replicación. Se trata de un grupo de servidores que mantienen el mismo conjunto de datos mediante replicación. Incluso puedes utilizar la replicación de MongoDB como parte del equilibrio de carga. Aquí, puedes distribuir las operaciones de escritura y lectura entre todas las instancias, en función del caso de uso.

¿Qué Es un Conjunto de Réplicas MongoDB?

Cada instancia de MongoDB que forma parte de un conjunto de réplicas determinado es un miembro. Cada conjunto de réplica debe tener un nodo primario y al menos un nodo secundario.

El nodo primario es el punto de acceso principal para las transacciones con el conjunto de réplicas. También es el único miembro que puede aceptar operaciones de escritura. La replicación copia primero el oplog (registro de operaciones) del primario. Después, repite los cambios registrados en los respectivos conjuntos de datos de los secundarios. Por lo tanto, cada conjunto de réplica sólo puede tener un nodo primario a la vez. Varios primarios que reciban operaciones de escritura pueden provocar conflictos de datos.

Normalmente, las aplicaciones sólo consultan al nodo primario para las operaciones de escritura y lectura. Puedes diseñar tu configuración para leer de uno o varios de los nodos secundarios. La transferencia asíncrona de datos puede hacer que las lecturas de los nodos secundarios sirvan datos antiguos. Por tanto, esta disposición no es ideal para todos los casos de uso.

Características del conjunto de réplicas

El mecanismo automático de conmutación por error diferencia a los conjuntos de réplica de MongoDB de su competencia. En ausencia de un primario, una elección automatizada entre los nodos secundarios elige un nuevo primario.

Conjunto de Réplica MongoDB vs Clúster MongoDB

Un conjunto de réplica MongoDB creará varias copias del mismo conjunto de datos en los nodos del conjunto de réplica. El objetivo principal de un conjunto de réplica es:

  • Ofrecer una solución de copia de seguridad integrada
  • Aumentar la disponibilidad de los datos

Un clúster MongoDB es un juego totalmente diferente. Distribuye los datos entre muchos nodos mediante una clave de fragmentación. Este proceso fragmentará los datos en muchos trozos llamados fragmentos. A continuación, copia cada fragmento en un nodo diferente. Un clúster pretende soportar grandes conjuntos de datos y operaciones de alto rendimiento. Lo consigue escalando horizontalmente la carga de trabajo.

Ésta es la diferencia entre un conjunto de réplicas y un clúster, en términos sencillos:

  • Un clúster distribuye la carga de trabajo. También almacena fragmentos de datos (shards) en muchos servidores.
  • Un conjunto de réplicas duplica el conjunto de datos por completo.

MongoDB te permite combinar estas funcionalidades creando un clúster fragmentado. Aquí, puedes replicar cada fragmento en un servidor secundario. Esto permite que un fragmento ofrezca una alta redundancia y disponibilidad de datos.

Mantener y configurar un conjunto de réplicas puede ser técnicamente agotador y llevar mucho tiempo. ¿Y encontrar el servicio de alojamiento adecuado? Eso es otro quebradero de cabeza. Con tantas opciones disponibles, es fácil perder horas investigando, en lugar de dedicarlas a construir tu negocio.

Permíteme informarte brevemente sobre una herramienta que hace todo esto y mucho más, para que puedas volver a machacarlo con tu servicio/producto.

La solución de Alojamiento de Aplicaciones de Kinsta, en la que confían más de 55.000 desarrolladores, puedes ponerla en marcha con sólo 3 sencillos pasos. Si te parece demasiado bueno para ser verdad, aquí tienes más ventajas de utilizar Kinsta:

  • Disfruta de un mejor rendimiento con las conexiones internas de Kinsta: Olvídate de tus problemas con las bases de datos compartidas. Pásate a bases de datos dedicados con conexiones internas que no tienen límites de número de consultas ni de filas. Kinsta es más rápido, más seguro y no te facturará el ancho de banda/tráfico interno.
  • Un características de funciones adaptadas a los desarrolladores: Escala tu aplicación en la sólida plataforma compatible con Gmail, YouTube y Google Search. Ten la seguridad de que aquí estás en las manos más seguras.
  • Disfruta de velocidades inigualables con el centro de datos que elijas: Elige la región que mejor se adapte a ti y a tus clientes. Con más de 25 centros de datos para elegir, los 260+ PoP de Kinsta garantizan la máxima velocidad y una presencia global para tu sitio web.

¡Prueba gratis la solución de alojamiento de aplicaciones de Kinsta hoy mismo!

¿Cómo Funciona la Replicación en MongoDB?

En MongoDB, envías operaciones de escritura al servidor (nodo) primario. El primario asigna las operaciones a través de los servidores secundarios, replicando los datos.

This is a flow-chart of how replication works in MongoDB, for 3 nodes (1 primary, 2 secondaries)
Ilustración del proceso de replicación de MongoDB (Fuente de la imagen: MongoDB)

Tres tipos de nodos MongoDB

De los tres tipos de nodos MongoDB, dos ya han aparecido antes: los nodos primarios y los secundarios. El tercer tipo de nodo MongoDB que resulta útil durante la replicación es un árbitro. El nodo árbitro no tiene una copia del conjunto de datos y no puede convertirse en primario. Dicho esto, el árbitro sí participa en las elecciones del primario.

Ya hemos mencionado lo que ocurre cuando el nodo primario se cae, pero ¿qué pasa si los nodos secundarios muerden el polvo? En ese caso, el nodo primario se convierte en secundario y la base de datos queda inaccesible.

Elección de miembros

Las elecciones pueden producirse en los siguientes escenarios:

  • Inicialización de un conjunto de réplicas
  • Pérdida de conectividad con el nodo primario (que puede detectarse mediante latidos)
  • Mantenimiento de un conjunto de réplicas mediante los métodos rs.reconfig o stepDown
  • Adición de un nuevo nodo a un conjunto de réplica existente

Un conjunto de réplica puede tener hasta 50 miembros, pero sólo 7 o menos pueden votar en cualquier elección.

El tiempo medio antes de que un conjunto elija un nuevo primario no debe superar los 12 segundos. El algoritmo de elección intentará que esté disponible el secundario con mayor prioridad. Al mismo tiempo, los miembros con un valor de prioridad 0 no pueden convertirse en primarios y no participan en la elección.

This is a diagram depicting a secondary node becoming a primary in MongoDB after the election.
Nodo secundario que se convierte en primario (Fuente de la imagen: Medium)

La preocupación por la escritura

Por durabilidad, las operaciones de escritura tienen un marco para copiar los datos en un número determinado de nodos. Con esto puedes incluso ofrecer información al cliente. Este marco también se conoce como «preocupación de escritura». Tiene miembros portadores de datos que deben reconocer una preocupación de escritura antes de que la operación vuelva como correcta. Generalmente, los conjuntos de réplicas tienen un valor de 1 como preocupación de escritura. Por tanto, sólo el primario debe confirmar la escritura antes de devolver la confirmación de escritura.

Puedes incluso aumentar el número de miembros necesarios para reconocer la operación de escritura. No hay límite para el número de miembros que puedes tener. Pero, si el número es elevado, tendrás que hacer frente a una latencia elevada. Esto se debe a que el cliente tiene que esperar el acuse de recibo de todos los miembros. Además, puedes establecer la preocupación de escritura de la «mayoría», que calcula más de la mitad de los miembros tras recibir su acuse de recibo.

Preferencia de lectura

Para las operaciones de lectura, puedes mencionar la preferencia de lectura que describe cómo la base de datos dirige la consulta a los miembros del conjunto de réplicas. Generalmente, el nodo primario recibe la operación de lectura, pero el cliente puede mencionar una preferencia de lectura para enviar las operaciones de lectura a los nodos secundarios. Estas son las opciones para la preferencia de lectura:

  • primaryPreferred: Normalmente, las operaciones de lectura proceden del nodo primario, pero si éste no está disponible, los datos se extraen de los nodos secundarios.
  • primary: Todas las operaciones de lectura proceden del nodo primario.
  • secondary: Todas las operaciones de lectura proceden de los nodos secundarios.
  • Closest: Aquí, las peticiones de lectura se dirigen al nodo alcanzable más cercano, que puede detectarse ejecutando el comando ping. El resultado de las operaciones de lectura puede proceder de cualquier miembro del conjunto de réplicas, independientemente de si es el primario o el secundario.
  • secondaryPreferred: Aquí, la mayoría de las operaciones de lectura proceden de los nodos secundarios, pero si ninguno de ellos está disponible, los datos se toman del nodo primario.

Sincronización de datos del Conjunto de Replicación

Para mantener copias actualizadas del conjunto de datos compartidos, los miembros secundarios de un conjunto de réplica replican o sincronizan los datos de otros miembros.

MongoDB aprovecha dos formas de sincronización de datos. Sincronización inicial para rellenar los nuevos miembros con el conjunto de datos completo. Replicación para ejecutar cambios continuos en el conjunto de datos completo.

Sincronización inicial

Durante la sincronización inicial, un nodo secundario ejecuta el comando init sync para sincronizar todos los datos del nodo primario con otro nodo secundario que contiene los datos más recientes. Por tanto, el nodo secundario aprovecha sistemáticamente la función tailable cursor para consultar las entradas oplog más recientes dentro de la colección local.oplog.rs del nodo primario y aplica estas operaciones dentro de estas entradas oplog.

A partir de MongoDB 5.2, las sincronizaciones iniciales pueden basarse en la copia de archivos o ser lógicas.

Sincronización lógica

Cuando ejecutas una sincronización lógica, MongoDB:

  1. Desarrolla todos los índices de las colecciones a medida que se copian los documentos de cada colección.
  2. Duplica todas las bases de datos excepto la base de datos local. mongod escanea cada colección en todas las bases de datos de origen e inserta todos los datos en sus duplicados de estas colecciones.
  3. Ejecuta todos los cambios en el conjunto de datos. Aprovechando el oplog de la fuente, el mongod actualiza su conjunto de datos para representar el estado actual del conjunto de réplicas.
  4. Extrae los registros oplog recién añadidos durante la copia de datos. Asegúrate de que el nodo de destino dispone de suficiente espacio en disco dentro de la base de datos local para almacenar provisionalmente estos registros oplog mientras dure esta etapa de copia de datos.

Cuando finaliza la sincronización inicial, el miembro pasa de STARTUP2 a SECONDARY .

Sincronización inicial basada en la copia de archivos

De entrada, sólo puedes ejecutar esto si utilizas MongoDB Enterprise. Este proceso ejecuta la sincronización inicial duplicando y moviendo los archivos en el sistema de archivos. Este método de sincronización puede ser más rápido que la sincronización inicial lógica en algunos casos. Ten en cuenta que la sincronización inicial basada en la copia de archivos puede dar lugar a recuentos inexactos si ejecutas el método count() sin un predicado de consulta.

Pero este método también tiene sus limitaciones:

  • Durante una sincronización inicial basada en copia de archivos, no puedes escribir en la base de datos local del nodo que se está sincronizando. Tampoco puedes ejecutar una copia de seguridad en el nodo con el que se está sincronizando ni en el miembro desde el que se está sincronizando.
  • Cuando se aprovecha el motor de almacenamiento cifrado, MongoDB utiliza la clave de origen para cifrar la de destino.
  • Sólo puedes ejecutar una sincronización inicial desde un nodo determinado cada vez.

Replicación

Los nodos secundarios replican los datos de forma consistente después de la sincronización inicial. Los nodos secundarios duplicarán el oplog de su sincronización desde el origen y ejecutarán estas operaciones en un proceso asíncrono.

Los secundarios son capaces de modificar automáticamente su sincronización desde el origen según sea necesario, basándose en los cambios en el tiempo de ping y en el estado de la replicación de otros nodos.

Replicación en flujo

Desde MongoDB 4.4, la sincronización desde las fuentes envía un flujo continuo de entradas oplog a sus secundarios de sincronización. La replicación en flujo reduce el retardo de replicación en redes de alta carga y latencia. También puede:

  • Disminuir el riesgo de perder operaciones de escritura con w:1 debido a la conmutación por error del primario.
  • Disminuir el estancamiento de las lecturas de los secundarios.
  • Reducir la latencia en las operaciones de escritura con w:“majority” y w:>1. En resumen, cualquier preocupación de escritura que necesite esperar a la replicación.
Replicación multihilo

MongoDB solía escribir operaciones por lotes a través de múltiples hilos para mejorar la concurrencia. MongoDB agrupa los lotes por id de documento mientras aplica cada grupo de operaciones con un hilo diferente.

MongoDB siempre ejecuta las operaciones de escritura en un documento dado en su orden de escritura original. Esto cambió en MongoDB 4.0.

A partir de MongoDB 4.0, las operaciones de lectura dirigidas a secundarios y configuradas con un nivel de preocupación de lectura de “majority” o “local” leerán ahora desde una instantánea WiredTiger de los datos si la lectura se produce en un secundario en el que se están aplicando los lotes de replicación. La lectura desde una instantánea garantiza una visión coherente de los datos, y permite que la lectura se produzca simultáneamente con la replicación en curso sin necesidad de bloqueo.

Por lo tanto, las lecturas secundarias que necesitan estos niveles de preocupación de lectura ya no necesitan esperar a que se apliquen los lotes de replicación y pueden gestionarse a medida que se reciben.

Cómo Crear un Conjunto de Réplicas MongoDB

Como hemos mencionado anteriormente, MongoDB maneja la replicación a través de conjuntos de réplica. En las siguientes secciones, mostraremos algunos métodos que puedes usar para crear conjuntos de réplica para tu caso de uso.

Método 1: Crear un nuevo conjunto de réplica de MongoDB en Ubuntu

Antes de empezar, tendrás que asegurarte de que tienes al menos tres servidores ejecutando Ubuntu 20.04, con MongoDB instalado en cada servidor.

Para configurar un conjunto de réplicas, es esencial proporcionar una dirección en la que cada nodo del conjunto de réplicas pueda ser alcanzado por los demás miembros del conjunto. En este caso, mantenemos tres nodos en el conjunto. Aunque podemos utilizar direcciones IP, no es recomendable, ya que las direcciones podrían cambiar inesperadamente. Una alternativa mejor puede ser utilizar los nombres de host DNS lógicos al configurar los conjuntos de réplica.

Podemos hacerlo configurando el subdominio para cada miembro de replicación. Aunque esto puede ser ideal para un entorno de producción, en esta sección se explicará cómo configurar la resolución DNS editando los respectivos archivos hosts de cada servidor. Este archivo nos permite asignar nombres de host legibles a direcciones IP numéricas. Así, si en algún momento cambia tu dirección IP, lo único que tienes que hacer es actualizar los archivos de hosts de los tres servidores, ¡en lugar de volver a configurar el conjunto de réplicas desde cero!

En general, hosts se almacena en el directorio /etc/. Repite los siguientes comandos para cada uno de tus tres servidores:

sudo nano /etc/hosts

En el comando anterior, estamos utilizando nano como editor de texto, sin embargo, puedes utilizar cualquier editor de texto que prefieras. Después de las primeras líneas que configuran el localhost, añade una entrada para cada miembro del conjunto de réplicas. Estas entradas tienen la forma de una dirección IP seguida del nombre legible por humanos que elijas. Aunque puedes darles el nombre que quieras, asegúrate de ser descriptivo para saber diferenciar a cada miembro. Para este tutorial, utilizaremos los siguientes nombres de host:

  • mongo0.replset.member
  • mongo1.replset.member
  • mongo2.replset.member

Utilizando estos nombres de host, tus archivos /etc/hosts tendrían un aspecto similar a las siguientes líneas resaltadas:

This is a snapshot of the /etc/hosts files containing the hostnames along with the IP address.
Ilustración de nombres de host

Guarda y cierra el archivo.

Después de configurar la resolución DNS para el conjunto de réplicas, tenemos que actualizar las reglas del cortafuegos para permitir que se comuniquen entre sí. Ejecuta el siguiente comando ufw en mongo0 para proporcionar a mongo1 acceso al puerto 27017 de mongo0:

sudo ufw allow from mongo1_server_ip to any port 27017

En lugar del parámetro mongo1_server_ip, introduce la dirección IP real de tu servidor mongo1. Además, si has actualizado la instancia de Mongo en este servidor para utilizar un puerto no predeterminado, asegúrate de cambiar 27017 para reflejar el puerto que utiliza tu instancia de MongoDB.

Ahora añade otra regla de cortafuegos para dar acceso a mongo2 al mismo puerto:

sudo ufw allow from mongo2_server_ip to any port 27017

En lugar del parámetro mongo2_server_ip, introduce la dirección IP real de tu servidor mongo2. A continuación, actualiza las reglas del cortafuegos de tus otros dos servidores. Ejecuta los siguientes comandos en el servidor mongo1, asegurándote de cambiar las direcciones IP en lugar del parámetro server_ip para reflejar las de mongo0 y mongo2, respectivamente:

sudo ufw allow from mongo0_server_ip to any port 27017
sudo ufw allow from mongo2_server_ip to any port 27017

Por último, ejecuta estos dos comandos en mongo2. De nuevo, asegúrate de introducir las direcciones IP correctas para cada servidor:

sudo ufw allow from mongo0_server_ip to any port 27017
sudo ufw allow from mongo1_server_ip to any port 27017

Tu siguiente paso es actualizar el archivo de configuración de cada instancia de MongoDB para permitir conexiones externas. Para permitir esto, necesitas modificar el archivo de configuración en cada servidor para reflejar la dirección IP e indicar el conjunto de réplicas. Aunque puedes utilizar cualquier editor de texto que prefieras, nosotros vamos a utilizar una vez más el editor de texto nano. Hagamos las siguientes modificaciones en cada archivo mongod.conf.

En mongo0:

# network interfaces
net:
port: 27017
bindIp: 127.0.0.1,mongo0.replset.member# replica set
replication:
replSetName: "rs0"

En mongo1:

# network interfaces
net:
port: 27017
bindIp: 127.0.0.1,mongo1.replset.member
replication:
replSetName: "rs0"

En mongo2:

# network interfaces
net:
port: 27017
bindIp: 127.0.0.1,mongo2.replset.member
replication:
replSetName: "rs0"
sudo systemctl restart mongod

Con esto, habrás habilitado la replicación para la instancia MongoDB de cada servidor.

Ahora puedes inicializar el conjunto de réplica utilizando el método rs.initiate(). Este método sólo debe ejecutarse en una única instancia MongoDB del conjunto de réplica. Asegúrate de que el nombre y el miembro del conjunto de réplica coinciden con las configuraciones que hiciste anteriormente en cada archivo de configuración.

rs.initiate(
  {
    _id: "rs0",
    members: [
      { _id: 0, host: "mongo0.replset.member" },
      { _id: 1, host: "mongo1.replset.member" },
      { _id: 2, host: "mongo2.replset.member" }
    ]
  }
)

Si el método devuelve «ok 1 en la salida, significa que el conjunto de réplica se inició correctamente. A continuación se muestra un ejemplo de cómo debería ser la salida:

 "ok": 1,
  "$clusterTime": {
    "clusterTime": Timestamp(1612389071, 1),
    "signature": {
      "hash": BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
      "keyId": NumberLong(0)
    }
  },
  "operationTime": Timestamp(1612389071, 1)
}

Apagar un servidor MongoDB

Puedes apagar un servidor MongoDB utilizando el método db.shutdownServer(). A continuación se muestra la sintaxis del mismo. Tanto force como timeoutsecs son parámetros opcionales.

db.shutdownServer({
  force: <boolean>,
  timeoutSecs: <int>
})

Este método puede fallar si el miembro del conjunto de réplicas mongod ejecuta ciertas operaciones como la creación de índices. Para interrumpir las operaciones y forzar el cierre del miembro, puedes introducir el parámetro booleano force a true.

Reiniciar MongoDB con –replSet

Para reiniciar la configuración, asegúrate de que todos los nodos de tu conjunto de réplicas están parados. A continuación, elimina la base de datos local de cada nodo. Vuelve a iniciarlo utilizando la bandera –replSet y ejecuta rs.initiate() en una sola instancia de mongod para el conjunto de réplica.

mongod --replSet "rs0"

rs.initiate() puede tomar un documento opcional de configuración del conjunto de réplica, a saber:

  • La opción Replication.replSetName o —replSet para especificar el nombre del conjunto de réplica en el campo _id.
  • La matriz de miembros, que contiene un documento por cada miembro del conjunto de réplica.

El método rs.initiate() desencadena una elección y elige a uno de los nodos para que sea el principal.

Añadir nodos al conjunto de réplica

Para añadir nodos al conjunto, inicia instancias de mongo en varias máquinas. A continuación, inicia un cliente mongo y utiliza el comando rs.add().

El comando rs.add() tiene la siguiente sintaxis básica:

rs.add(HOST_NAME:PORT)

Por ejemplo

Supón que mongo1 es tu instancia de mongod, y que está escuchando en el puerto 27017. Utiliza el comando cliente de Mongo rs.add() para añadir esta instancia al conjunto de réplicas.

rs.add("mongo1:27017")

Sólo cuando estés conectado al nodo primario podrás añadir una instancia mongod al conjunto de réplicas. Para comprobar si estás conectado al primario, utiliza el comando db.isMaster().

Eliminar usuarios

Para eliminar un nodos, podemos utilizar rs.remove()

Para ello, en primer lugar, apaga la instancia de mongod que deseas eliminar utilizando el método db.shutdownServer() del que hemos hablado anteriormente.

A continuación, conéctate al primario actual del conjunto de réplicas. Para determinar el primario actual, utiliza db.hello() mientras estás conectado a cualquier miembro del conjunto de réplicas. Una vez que hayas determinado el primario, ejecuta cualquiera de los siguientes comandos:

rs.remove("mongodb-node-04:27017")
rs.remove("mongodb-node-04")
This is a snapshot of the output after carrying out the rs.remove() command.
La imagen anterior muestra que el nodo se ha eliminado correctamente del conjunto de réplicas. (Fuente de la imagen: Bmc)

Si el conjunto de réplica necesita elegir un nuevo primario, MongoDB podría desconectar brevemente el nodo. En este caso, volverá a conectarse automáticamente. Además, puede mostrar un error DBClientCursor::init call() failed aunque el comando se ejecute correctamente.

Método 2: Configurar un conjunto de réplicas de MongoDB para el despliegue y las pruebas

En general, puedes configurar conjuntos de réplica para pruebas con RBAC activado o desactivado. En este método, configuraremos conjuntos de réplica con el control de acceso deshabilitado para desplegarlos en un entorno de pruebas.

En primer lugar, crea directorios para todas las instancias que formen parte del conjunto de réplica utilizando el siguiente comando:

mkdir -p /srv/mongodb/replicaset0-0  /srv/mongodb/replicaset0-1 /srv/mongodb/replicaset0-2

Este comando creará directorios para tres instancias MongoDB replicaset0-0, replicaset0-1 y replicaset0-2. Ahora, inicia las instancias MongoDB para cada una de ellas utilizando el siguiente conjunto de comandos:

Para el Servidor 1:

mongod --replSet replicaset --port 27017 --bind_ip localhost,<hostname(s)|ip address(es)> --dbpath /srv/mongodb/replicaset0-0  --oplogSize 128

Para el Servidor 2:

mongod --replSet replicaset --port 27018 --bind_ip localhost,<hostname(s)|ip address(es)> --dbpath /srv/mongodb/replicaset0-0  --oplogSize 128

Para el Servidor 3:

mongod --replSet replicaset --port 27019 --bind_ip localhost,<hostname(s)|ip address(es)> --dbpath /srv/mongodb/replicaset0-0  --oplogSize 128

El parámetro –oplogSize se utiliza para evitar que la máquina se sobrecargue durante la fase de prueba. Ayuda a reducir la cantidad de espacio que consume cada disco.

Ahora, conéctate a una de las instancias utilizando el shell de Mongo conectándote mediante el número de puerto que se indica a continuación.

mongo --port 27017

Podemos utilizar el comando rs.initiate() para iniciar el proceso de replicación. Tendrás que sustituir el parámetro hostname por el nombre de tu sistema.

rs conf = {

  _id: "replicaset0",

  members: [

    {  _id: 0,  host: "<hostname>:27017},

    {  _id: 1,  host: "<hostname>:27018"},

    {  _id: 2,  host: "<hostname>:27019"}

   ] }

Ahora puedes pasar el archivo objeto de configuración como parámetro para el comando iniciar y utilizarlo de la siguiente manera:

rs.initiate(rsconf)

¡Y ya está! Has creado con éxito un conjunto de réplica de MongoDB para fines de desarrollo y pruebas.

Método 3: Transformar una instancia independiente en un conjunto de réplica MongoDB

MongoDB permite a sus usuarios transformar sus instancias autónomas en conjuntos de réplica. Mientras que las instancias autónomas se utilizan principalmente para la fase de pruebas y desarrollo, los conjuntos de réplica forman parte del entorno de producción.

Para empezar, cerremos nuestra instancia mongod utilizando el siguiente comando:

db.adminCommand({"shutdown":"1"})

Reinicia tu instancia utilizando el parámetro –repelSet en tu comando para especificar el conjunto de réplica que vas a utilizar:

mongod --port 27017 – dbpath /var/lib/mongodb  --replSet replicaSet1 --bind_ip localhost,<hostname(s)|ip address(es)>

Debes especificar el nombre de tu servidor junto con la dirección única en el comando.

Conecta el shell con tu instancia MongoDB y utiliza el comando iniciar para iniciar el proceso de replicación y convertir con éxito la instancia en un conjunto de réplica. Puedes realizar todas las operaciones básicas como añadir o eliminar una instancia utilizando los siguientes comandos:

rs.add(“<host_name:port>”)
rs.remove(“host-name”)

Además, puedes comprobar el estado de tu conjunto de réplicas de MongoDB utilizando los comandos rs.status() y rs.conf().

Método 4: Atlas MongoDB – Una alternativa más sencilla

La replicación y la fragmentación pueden funcionar juntas para formar algo llamado clúster fragmentado. Aunque la instalación y la configuración pueden llevar bastante tiempo, MongoDB Atlas es una alternativa mejor que los métodos mencionados anteriormente.

Automatiza tus conjuntos de réplicas, haciendo que el proceso sea fácil de implementar. Puedes desplegar conjuntos de réplica fragmentados globalmente con unos pocos clics, lo que permite la recuperación ante desastres, una administración más sencilla, localización de datos y despliegues multirregión.

En MongoDB Atlas, tenemos que crear clústeres, que pueden ser un conjunto de réplicas o un clúster fragmentado. Para un proyecto concreto, el número de nodos de un clúster en otras regiones está limitado a un total de 40.

Esto excluye los clusters libres o compartidos y las regiones de la nube de Google que se comunican entre sí. El número total de nodos entre dos regiones cualesquiera debe cumplir esta limitación. Por ejemplo, si hay un proyecto en el que:

  • La región A tiene 15 nodos.
  • La región B tiene 25 nodos
  • La región C tiene 10 nodos

Sólo podemos asignar 5 nodos más a la región C ya que,

  1. Región A+ Región B = 40; cumple la restricción de que 40 es el número máximo de nodos permitido.
  2. Región B+ Región C = 25+10+5 (Nodos adicionales asignados a C) = 40; cumple la restricción de que 40 es el número máximo de nodos permitido.
  3. Región A+ Región C =15+10+5 (Nodos adicionales asignados a C) = 30; cumple la restricción de que 40 es el número máximo de nodos permitido.

Si asignamos 10 nodos más a la región C, haciendo que la región C tenga 20 nodos, entonces Región B + Región C = 45 nodos. Esto superaría la restricción dada, por lo que es posible que no puedas crear un clúster multirregión.

Cuando creas un clúster, Atlas crea un contenedor de red en el proyecto para el proveedor de la nube, si no estaba allí previamente. Para crear un clúster de conjunto de réplicas en MongoDB Atlas, ejecuta el siguiente comando en la CLI de Atlas:

atlas clusters create [name] [options]

Asegúrate de dar un nombre de clúster descriptivo, ya que no se puede cambiar una vez creado el clúster. El argumento puede contener letras ASCII, números y guiones.

Hay varias opciones disponibles para la creación de clústeres en MongoDB en función de tus requisitos. Por ejemplo, si quieres una copia de seguridad continua en la nube para tu clúster, establece --backup como verdadero.

Cómo Gestionar el Retraso de la Replicación

El retardo de replicación puede ser bastante desagradable. Es un retraso entre una operación en el primario y la aplicación de esa operación desde el oplog al secundario. Si tu empresa trabaja con grandes conjuntos de datos, es de esperar que se produzca un retraso dentro de un cierto umbral. Sin embargo, a veces también pueden contribuir factores externos y aumentar el retraso. Para beneficiarte de una replicación actualizada, asegúrate de que

  1. Diriges tu tráfico de red con un ancho de banda estable y suficiente. La latencia de la red desempeña un papel muy importante a la hora de afectar a tu replicación, y si la red es insuficiente para satisfacer las necesidades del proceso de replicación, se producirán retrasos en la replicación de datos en todo el conjunto de réplicas.
  2. Tienes un rendimiento de disco suficiente. Si el sistema de archivos y el dispositivo de disco del secundario no son capaces de volcar datos al disco con la misma rapidez que el primario, el secundario tendrá dificultades para mantener el ritmo. Por lo tanto, los nodos secundarios procesan las consultas de escritura más lentamente que el nodo primario. Éste es un problema común en la mayoría de los sistemas multiinquilino, incluidas las instancias virtualizadas y los despliegues a gran escala.
  3. Solicita una consulta de escritura después de un intervalo para dar a los secundarios la oportunidad de ponerse al día con el primario, especialmente cuando quieras realizar una operación de carga masiva o de ingestión de datos que requiera un gran número de escrituras en el primario. Los secundarios no podrán leer el oplog con la rapidez suficiente para seguir el ritmo de los cambios, sobre todo si hay problemas de escritura no reconocidos.
  4. Identifica las tareas en segundo plano en ejecución. Algunas tareas, como los trabajos cron, las actualizaciones del servidor y las comprobaciones de seguridad, pueden tener efectos inesperados en la red o en el uso del disco, provocando retrasos en el proceso de replicación.

Si no estás seguro de si hay un retraso en la replicación de tu aplicación, no te preocupes: ¡en la siguiente sección se tratan las estrategias de solución de problemas!

Resolución de Problemas de los Conjuntos de Réplica de MongoDB

Has configurado con éxito tus conjuntos de réplica, pero notas que tus datos son incoherentes entre servidores. Esto es muy alarmante para las empresas a gran escala, sin embargo, con métodos rápidos de solución de problemas , ¡puedes encontrar la causa o incluso corregir el problema! A continuación se indican algunas estrategias habituales para solucionar problemas de despliegue de conjuntos de réplicas que pueden resultarte útiles:

Comprobar el estado de la réplica

Podemos comprobar el estado actual del conjunto de réplica y el estado de cada nodo ejecutando el siguiente comando en una sesión de mongosh que esté conectada al primario de un conjunto de réplica.

 rs.status()

Comprueba el retraso en la replicación

Como ya hemos comentado, el retardo de replicación puede ser un problema grave, ya que hace que los miembros «rezagados» no puedan convertirse rápidamente en primarios y aumenta la posibilidad de que las operaciones de lectura distribuida sean incoherentes. Podemos comprobar la longitud actual del registro de replicación utilizando el siguiente comando:

rs.printSecondaryReplicationInfo()

Esto devuelve el valor syncedTo, que es la hora a la que se escribió la última entrada oplog en el secundario para cada miembro. He aquí un ejemplo para demostrar lo mismo:

source: m1.example.net:27017
    syncedTo: Mon Oct 10 2022 10:19:35 GMT-0400 (EDT)
    0 secs (0 hrs) behind the primary
source: m2.example.net:27017
    syncedTo: Mon Oct 10 2022 10:19:35 GMT-0400 (EDT)
    0 secs (0 hrs) behind the primary

Un nodo retrasado puede mostrarse como 0 segundos por detrás del primario cuando el periodo de inactividad en el primario es mayor que el valor members[n].secondaryDelaySecs.

Probar las conexiones entre todos los nodos

Cada miembro de un conjunto de réplicas debe poder conectarse con todos los demás nodos. Asegúrate siempre de verificar las conexiones en ambas direcciones. En la mayoría de los casos, las configuraciones de cortafuegos o las topologías de red impiden la conectividad normal y necesaria, lo que puede bloquear la replicación.

Por ejemplo, supongamos que la instancia mongod se vincula tanto a localhost como a hostname ‘ExampleHostname’, que está asociado a la dirección IP 198.41.110.1:

mongod --bind_ip localhost, ExampleHostname

Para conectarse a esta instancia, los clientes remotos deben especificar el nombre de host o la Dirección IP:

mongosh --host ExampleHostname
mongosh --host 198.41.110.1

Si un conjunto de réplicas consta de tres miembros, m1, m2 y m3, utilizando el puerto por defecto 27017, debes probar la conexión como se indica a continuación:

En m1:

mongosh --host m2 --port 27017
mongosh --host m3 --port 27017

En m2:

mongosh --host m1 --port 27017
mongosh --host m3 --port 27017

En m3:

mongosh --host m1 --port 27017
mongosh --host m2 --port 27017

Si falla alguna conexión en cualquier dirección, tendrías que comprobar la configuración de tu cortafuegos y reconfigurarlo para permitir las conexiones.

Garantizar la Seguridad de las Comunicaciones con la Autenticación de Archivos de Claves

Por defecto, la autenticación de archivos de claves en MongoDB se basa en el mecanismo de autenticación de respuesta de desafío salado (SCRAM – salted challenge response authentication mechanism). Para ello, MongoDB debe leer y validar las credenciales proporcionadas por el usuario, que incluyen una combinación del nombre de usuario, la contraseña y la base de datos de autenticación que conoce la instancia específica de MongoDB. Este es el mecanismo exacto que se utiliza para autenticar a los usuarios que proporcionan una contraseña al conectarse a la base de datos.

Cuando activas la autenticación en MongoDB, se activa automáticamente el Control de Acceso Basado en Roles (RBAC) para el conjunto de réplicas, y se concede al usuario uno o varios roles que determinan su acceso a los recursos de la base de datos. Cuando se habilita el RBAC, significa que sólo el usuario válido de Mongo autenticado y con los privilegios adecuados podrá acceder a los recursos del sistema.

El archivo de claves actúa como una contraseña compartida para cada miembro del clúster. Esto permite que cada instancia de Mongo en el conjunto de réplicas utilice el contenido del archivo de claves como contraseña compartida para autenticar a otros miembros en el despliegue.

Sólo las instancias mongod con el archivo de claves correcto pueden unirse al conjunto de réplica. La longitud de una clave debe estar comprendida entre 6 y 1024 caracteres y sólo puede contener caracteres del conjunto base64. Ten en cuenta que MongoDB elimina los espacios en blanco al leer las claves.

Puedes generar un archivo de claves utilizando varios métodos. En este tutorial, utilizamos openssl para generar una cadena compleja de 1024 caracteres aleatorios para utilizarla como contraseña compartida. A continuación, utiliza chmod para cambiar los permisos del archivo y proporcionar permisos de lectura sólo para el propietario del archivo. Evita almacenar el archivo de claves en medios de almacenamiento que puedan desconectarse fácilmente del hardware que aloja las instancias de mongod, como una unidad USB o un dispositivo de almacenamiento conectado a la red. A continuación se muestra el comando para generar un archivo de claves:

openssl rand -base64 756 > <path-to-keyfile>
chmod 400 <path-to-keyfile>

A continuación, copia el archivo de claves en cada nodo del conjunto de réplicas. Asegúrate de que el usuario que ejecuta las instancias mongod es el propietario del archivo y puede acceder al archivo de claves. Una vez hecho lo anterior, apaga todos los miembros del conjunto de réplica empezando por los secundarios. Una vez que todos los secundarios estén desconectados, puedes seguir adelante y apagar el primario. Es esencial seguir este orden para evitar posibles retrocesos. Ahora apaga la instancia mongod ejecutando el siguiente comando:

use admin
db.shutdownServer()

Una vez ejecutado el comando, todos los nodos del conjunto de réplicas estarán desconectados. Ahora, reinicia cada nodo del conjunto de réplicas con el control de acceso activado.

Para cada miembro del conjunto de réplicas, inicia la instancia mongod con la configuración del archivo de configuración security.keyFile o con la opción de línea de comandos --keyFile.

Si utilizas un archivo de configuración, establece

  • security.keyFile a la ruta del archivo de claves, y
  • replication.replSetName al nombre del conjunto de réplica.
security:
  keyFile: <path-to-keyfile>
replication:
  replSetName: <replicaSetName>
net:
   bindIp: localhost,<hostname(s)|ip address(es)>

Inicia la instancia mongod utilizando el archivo de configuración:

mongod --config <path-to-config-file>

Si utilizas las opciones de la línea de comandos, inicia la instancia de mongod con las siguientes opciones:

  • –keyFile establecido en la ruta del archivo de claves, y
  • –replSet con el nombre del conjunto de réplicas.
mongod --keyFile <path-to-keyfile> --replSet <replicaSetName> --bind_ip localhost,<hostname(s)|ip address(es)>

Puedes incluir opciones adicionales según requiera tu configuración. Por ejemplo, si deseas que clientes remotos se conecten a tu despliegue o los miembros de tu despliegue se ejecutan en distintos hosts, especifica –bind_ip. Para más información, consulta Cambios en la compatibilidad de enlace localhost.

A continuación, conéctate a un nodo del conjunto de réplicas a través de la interfaz localhost. Debes ejecutar mongosh en la misma máquina física que la instancia de mongod. Esta interfaz sólo está disponible cuando no se han creado usuarios para la implantación y se cierra automáticamente tras la creación del primer usuario.

A continuación, iniciamos el conjunto de réplicas. Desde mongosh, ejecuta el método rs.initiate():

rs.initiate(
  {
    _id: "myReplSet",
    members: [
      { _id: 0, host: "mongo1:27017" },
      { _id: 1, host: "mongo2:27017" },
      { _id: 2, host: "mongo3:27017" }
    ]
  }
)

Como ya hemos comentado, este método elige a uno de los nodos para que sea el nodo primario del conjunto de réplica. Para localizar al nodo primario, utiliza rs.status(). Conéctate al primario antes de continuar.

Ahora, crea el usuario administrador. Puedes añadir un usuario utilizando el método db.createUser(). Asegúrate de que el usuario tenga al menos el rol userAdminAnyDatabase en la base de datos admin.

El siguiente ejemplo crea el usuario ‘batman’ con el rol userAdminAnyDatabase en la base de datos admin:

admin = db.getSiblingDB("admin")
admin.createUser(
  {
    user: "batman",
    pwd: passwordPrompt(), // or cleartext password
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

Introduce la contraseña creada anteriormente cuando se te solicite.

A continuación, debes autenticarte como usuario administrador. Para ello, utiliza db.auth() para autenticarte. Por ejemplo

db.getSiblingDB(«admin»).auth(«batman», passwordPrompt()) // o contraseña en texto claro

Como alternativa, puedes conectar una nueva instancia de mongosh al nodo primario del conjunto de réplicas utilizando los parámetros -u <username>, -p <password> y --authenticationDatabase.

mongosh -u "batman" -p  --authenticationDatabase "admin"

Aunque no especifiques la contraseña en el campo de la línea de comandos -p, mongosh te pedirá la contraseña.

Por último, crea el administrador del clúster. El rol clusterAdmin da acceso a las operaciones de replicación, como la configuración del conjunto de réplicas.

Vamos a crear un usuario administrador del clúster y a asignarle el rol clusterAdmin en la base de datos admin:

db.getSiblingDB("admin").createUser(
  {
    "user": "robin",
    "pwd": passwordPrompt(),     // or cleartext password
    roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
  }
)

Introduce la contraseña cuando se te solicite.

Si lo deseas, puedes crear usuarios adicionales para permitir clientes e interactuar con el conjunto de réplicas.

¡Listo! ¡Has activado con éxito la autenticación por fichero de claves!

Resumen

La replicación ha sido un requisito esencial en lo que respecta a las bases de datos, sobre todo a medida que aumentan las empresas. Mejora ampliamente el rendimiento, la seguridad de los datos y la disponibilidad del sistema. Hablando de rendimiento, es fundamental para tu base de datos de WordPress controlar los problemas de rendimiento y rectificarlos en el momento oportuno, por ejemplo, con Kinsta APM, Jetpack y Freshping, por nombrar algunos.

La replicación ayuda a garantizar la protección de los datos en varios servidores y evita que tus servidores sufran graves periodos de inactividad (o peor aún, que pierdan tus datos por completo). En este artículo, cubrimos la creación de un conjunto de réplicas y algunos consejos para solucionar problemas, junto con la importancia de la replicación. ¿Utilizas la replicación de MongoDB en tu empresa y te ha resultado útil? ¡Háznoslo saber en la sección de comentarios más abajo!

Jeremy Holcombe Kinsta

Content & Marketing Editor at Kinsta, WordPress Web Developer, and Content Writer. Outside of all things WordPress, I enjoy the beach, golf, and movies. I also have tall people problems ;).