mongodb amazon-web-services cluster-computing autoscaling amazon-cloudformation

Clúster de Mongodb con formación de nubes aws y escalamiento automático



amazon-web-services cluster-computing (1)

Esta es una muy buena pregunta y he pasado por este viaje muy doloroso recientemente. Estoy escribiendo una respuesta bastante extensa aquí con la esperanza de que algunos de estos pensamientos de ejecutar un clúster MongoDB a través de CloudFormation sean útiles para otros.

Supongo que está creando un clúster de producción de MongoDB de la siguiente manera:

  • 3 servidores de configuración (las instancias de micros / smalls pueden trabajar aquí)
  • Al menos 1 fragmento que consta de, por ejemplo, 2 instancias de fragmento (principal y secundario) (mínimo o grande) con discos grandes configurados para discos de datos / registro / diario.
  • Máquina de árbitro para la votación (micro probablemente OK).

es decir, https://docs.mongodb.org/manual/core/sharded-cluster-architectures-production/

Al igual que usted, inicialmente probé la plantilla de AWS MongoDB CloudFormation que publicó en el enlace ( https://s3.amazonaws.com/quickstart-reference/mongodb/latest/templates/MongoDB-VPC.template ) pero, para ser sincero, fue mucho, demasiado complejo, es decir, tiene 9,300 líneas de largo y configura múltiples servidores (es decir, fragmentos de réplica, configuraciones, árbitros, etc.). La ejecución de la plantilla de CloudFormation demoró mucho y siguió fallando (p. Ej., Después de 15 minutos), lo que significaba que todos los servidores terminaron de nuevo y tuve que volver a intentarlo, lo cual fue realmente frustrante y me llevó mucho tiempo.

La solución que elegí al final (con la que estoy muy feliz) fue crear plantillas separadas para cada tipo de servidor MongoDB en el clúster, por ejemplo

  1. MongoDbConfigServer.template (plantilla para crear servidores de configuración - ejecutar esto 3 veces)
  2. MongoDbShardedReplicaServer.template (plantilla para crear una réplica: ejecute 2 veces para cada fragmento)
  3. MongoDbArbiterServer.template (plantilla para crear un árbitro: ejecutar una vez para cada fragmento)

NOTA: plantillas disponibles en https://github.com/adoreboard/aws-cloudformation-templates

La idea entonces es abrir cada servidor en el clúster individualmente, es decir, 3 servidores de configuración, 2 servidores de réplica fragmentada (para 1 fragmento) y un árbitro. Luego puede agregar parámetros personalizados en cada una de las plantillas, por ejemplo, los parámetros para el servidor de réplica podrían incluir:

  • InstanceType por ejemplo, t2.micro
  • ReplicaSetName por ejemplo, s1r (fragmento 1 réplica)
  • ReplicaSetNumber por ejemplo, 2 (usado con ReplicaSetName para crear un nombre, por ejemplo, el nombre se convierte en s1r2 )
  • VpcId por ejemplo, vpc-e4ad2b25 ( vpc-e4ad2b25 no es una VPC real)
  • SubnetId subnet-2d39a157 por ejemplo, subnet-2d39a157 ( subnet-2d39a157 no es una subred real)
  • GroupId (nombre del ID de grupo de MongoDB existente)
  • Route53 (booleano para agregar un registro a un DNS interno - mejores prácticas)
  • Route53HostedZone (si el valor booleano es verdadero, entonces la ID del DNS interno mediante Route53)

Lo realmente genial de CloudFormation es que estos parámetros personalizados pueden tener (a) una descripción útil para las personas que la ejecutan, (b) tipos especiales (por ejemplo, cuando se ejecuta un cuadro combinado prefiltrado, por lo que los errores son más difíciles de cometer) y (c) los valores predeterminados . Aquí hay un ejemplo:

"Route53HostedZone": { "Description": "Route 53 hosted zone for updating internal DNS (Only applicable if the parameter [ UpdateRoute53 ] = /"true/"", "Type": "AWS::Route53::HostedZone::Id", "Default": "YA3VWJWIX3FDC" },

Esto hace que la ejecución de la plantilla de CloudFormation sea una brisa absoluta, ya que muchas veces podemos confiar en los valores predeterminados y modificar solo un par de cosas dependiendo de la instancia del servidor que estamos creando (o reemplazando).

Además de los parámetros, cada una de las 3 plantillas mencionadas anteriormente tiene una sección de "Resources" que crea la instancia. También podemos hacer cosas geniales a través de la sección "AWS::CloudFormation::Init" . p.ej

"Resources": { "MongoDbConfigServer": { "Type": "AWS::EC2::Instance", "Metadata": { "AWS::CloudFormation::Init": { "configSets" : { "Install" : [ "Metric-Uploading-Config", "Install-MongoDB", "Update-Route53" ] },

Los "configSets" en el ejemplo anterior muestran que crear un servidor MongoDB no es simplemente una cuestión de crear una instancia de AWS e instalar MongoDB en él, sino que también podemos (a) instalar las métricas de disco / memoria de CloudWatch (b) actualizar Route53 DNS, etc. La idea es que desee automatizar cosas como DNS / Monitoreo, etc. tanto como sea posible.

La IMO, la creación de una plantilla y, por lo tanto, una pila para cada servidor tiene la gran ventaja de poder reemplazar un servidor de manera extremadamente rápida a través de la consola web de CloudFormation. Además, como tenemos un servidor por plantilla , es fácil construir el clúster MongoDB poco a poco.

Mi último consejo para crear las plantillas sería copiar lo que funciona para usted de otras plantillas de GitHub MongoDB CloudFormation, por ejemplo, utilicé lo siguiente para crear los servidores de réplica para usar RAID10 (en lugar de los discos IOPS aprovisionados AWS, que son mucho más caros).

https://github.com/CaptainCodeman/mongo-aws-vpc/blob/master/src/templates/mongo-master.template

En su pregunta mencionó la escala automática: mi preferencia sería agregar un fragmento / reemplazar una instancia rota manualmente (la escala automática tiene sentido con los contenedores web, por ejemplo, Tomcat / Apache, pero un clúster MongoDB debería crecer lentamente con el tiempo). Sin embargo, el monitoreo es muy importante, especialmente los tamaños de disco en los servidores de fragmentos para avisarle cuando se están llenando los discos (por lo que puede agregar un nuevo fragmento para eliminar datos). El monitoreo se puede lograr con bastante facilidad usando las métricas / alarmas de AWS CloudWatch o usando el servicio MMS de MongoDB.

Si un nodo se cae, por ejemplo, una de las réplicas de un fragmento, simplemente puede matar el servidor, volver a crearlo utilizando su plantilla de CloudFormation y los discos se sincronizarán automáticamente. Este es mi flujo normal si una instancia falla y generalmente no es necesario volver a configurarla. He perdido demasiadas horas en el pasado tratando de arreglar servidores, a veces afortunado / a veces no. Mi estrategia de copia de seguridad ahora es ejecutar una gran mongodump de las colecciones importantes de la base de datos una vez al día a través de un crontab , zip y subir a AWS S3. Esto significa que si ocurre la opción nuclear (corrupción de la base de datos completa) podemos recrear toda la base de datos y el mongorestore datos en una hora o 2.

Sin embargo, si creas un nuevo fragmento (porque te estás quedando sin espacio) la configuración es necesaria. Por ejemplo, si agrega un nuevo fragmento 3 , creará 2 nodos de réplica (por ejemplo, primario con nombre => mongo-s3r1 / secundario con nombre => mongo-s3r2 ) y 1 árbitro (por ejemplo, con el nombre mongo-s3r-arb ) luego se conectaría a través de un shell MongoDB a un mongos (enrutador MongoDB) y ejecutaría este comando: -

sh.addShard("s3r/mongo-s3r1.internal.mycompany.com:27017,mongo-s3r2.internal.mycompany.com:27017")

NOTA: - Este comando asume que está usando un DNS privado a través de Route53 (la mejor práctica). Simplemente puede usar las direcciones IP privadas de las 2 réplicas en el comando addShard pero en el pasado me han quemado mucho (por ejemplo, varios meses atrás, todas las instancias de AWS se reiniciaron y se generaron nuevas direcciones IP privadas para todas ellas. El clúster de MongoDB me tomó 2 días, ya que tuve que reconfigurar todo manualmente, mientras que cambiar las IP en Route53 toma algunos segundos ... ;-)

Podría argumentar que también deberíamos agregar el comando addShard a otra plantilla de CloudFormation, pero IMO esto agrega una complejidad innecesaria porque tiene que conocer un servidor que tiene un enrutador MongoDB ( mongos ) y conectarse a ese para ejecutar el comando addShard . Por lo tanto, simplemente ejecuto esto después de que se hayan creado las instancias en un nuevo fragmento MongoDB.

De todos modos, esos son mis pensamientos más bien confusos sobre el asunto. ¡Lo principal es que una vez que tenga las plantillas en su lugar, su vida se vuelve mucho más fácil y definitivamente vale la pena! ¡La mejor de las suertes! :-)

He estado investigando la creación de mi propio clúster mongodb en AWS. Aws mongodb plantilla proporciona algunos buenos puntos de partida. Sin embargo, no cubre la escala automática o cuando un nodo se cae. Por ejemplo, si tengo 1 nodo primario y 2 secundarios. Y lo principal se reduce y se activa la escala automática. ¿Cómo agregaría la nueva instancia mongodb al conjunto de réplicas?

Si observa la plantilla, utiliza un script init.sh para verificar si el nodo que se está lanzando es un nodo primario y espera a que existan todos los demás nodos y crea un conjunto de réplicas con sus direcciones IP en el primario. Cuando el conjunto de réplicas se configura de manera única, todos los nodos ya existen.

No solo eso, sino que mi aplicación de nodo usa la mangosta. Parte de la conexión de la base de datos le permite especificar varios nodos. Cómo realizar un seguimiento de lo que está funcionando actualmente (creo que podría usar DynamoDB pero no estoy seguro).

¿Cuál es el flujo habitual si una instancia falla? ¿La gente generalmente reconfigura los clusters manualmente si esto sucede?

¿Alguna idea? Gracias.