Alta disponibilidad de MongoDB en producción: conjuntos de réplicas, fragmentación y operadores Kubernetes
MongoDB HA con conjuntos de réplicas, fragmentación y operadores Kubernetes
MongoDB ocupa una posición única en el panorama de las bases de datos. Su modelo de documento se asigna naturalmente a los objetos de la aplicación, su esquema flexible se adapta a estructuras de datos en evolución sin migraciones, y sus primitivas de replicación y fragmentación incorporadas brindan una base para la alta disponibilidad y el escalamiento horizontal que las bases de datos relacionales requieren herramientas externas para lograr. Pero un cimiento no es un edificio terminado. Ejecutar MongoDB en producción con alta disponibilidad genuina, donde una falla de nodo, una partición de red o una región completa fuera de línea no resulta en tiempo de inactividad o pérdida de datos, exige una arquitectura deliberada, un ajuste cuidadoso y una disciplina operativa rigurosa.
Esta guía recorre cada capa de MongoDB HA: desde el protocolo de consenso del conjunto de réplicas y la replicación de registros de operaciones que impulsan la conmutación por error automática, pasando por la arquitectura de clúster fragmentado que permite el escalamiento horizontal, hasta los operadores Kubernetes que automatizan la administración del ciclo de vida y las opciones de implementación en AWS, Azure, GCP y k3s bare metal con Rancher. Cada sección incluye configuración concreta, manifiestos YAML y procedimientos operativos que puede adaptar a su entorno.
MongoDB Arquitectura del conjunto de réplicas
Un conjunto de réplicas es la unidad fundamental de alta disponibilidad de MongoDB. Es un grupo de procesosmongodque mantienen el mismo conjunto de datos. Un miembro es elprimario, que recibe todas las operaciones de escritura. Los miembros restantes sonsecundarios, que replican datos del primario siguiendo su registro de operaciones (oplog). Si el primario deja de estar disponible, el conjunto de réplicas realiza una elección para elegir un nuevo primario entre los secundarios elegibles, generalmente en un plazo de 10 a 12 segundos.
Un conjunto de réplicas de producción debe tener al menos tres miembros con datos, idealmente distribuidos en diferentes dominios de falla (zonas de disponibilidad, bastidores o centros de datos). Esto garantiza que el conjunto de réplicas pueda sobrevivir a la pérdida de cualquier miembro y aún mantener una mayoría a efectos electorales. Un árbitroopcional,, participa en las elecciones pero no retiene datos; existe únicamente para romper empates cuando tiene un número par de miembros con datos, aunque la mejor práctica de MongoDB es utilizar un número impar de miembros con datos.
Mecánica de replicación y registro de operaciones
El registro de operaciones es una colección limitada (local.oplog.rs) que registra cada operación de modificación de datos en el primario en forma idempotente. Los secundarios siguen continuamente el registro de operaciones del primario y aplican operaciones localmente. El tamaño del registro de operaciones determina qué tan atrás puede quedar un secundario antes de que necesite una resincronización completa; para cargas de trabajo de producción, dimensione el registro de operaciones para que contenga al menos de 24 a 72 horas de actividad de escritura. MongoDB 4.4+ admite el tamaño dinámico de registros de operaciones a través dereplSetResizeOplog.
# Check current oplog size and window
rs.printReplicationInfo()
# Resize the oplog to 50 GB
db.adminCommand({ replSetResizeOplog: 1, size: 51200 })
# Check replication lag on secondaries
rs.printSecondaryReplicationInfo()Elecciones y protocolo basado en balsa
MongoDB 4.0+ utiliza un protocolo de consenso inspirado en Raft para elecciones de conjuntos de réplicas. Cuando un secundario detecta que el primario es inalcanzable (electionTimeoutMillispredeterminado de 10,000 ms), puede convocar una elección. Para ganar, un candidato debe recibir los votos de la mayoría de los miembros votantes. El miembro con la entrada más reciente al registro de operaciones y la mayor prioridad gana si hay varios candidatos elegibles. Puede influir en los resultados de las elecciones estableciendo las prioridades de los miembros: un miembro conpriority: 0nunca puede convertirse en principal, lo cual es útil para réplicas de análisis o miembros en regiones remotas.
# Initiate a 3-member replica set
rs.initiate({
_id: "rs-production",
members: [
{ _id: 0, host: "mongo-0.mongo-svc:27017", priority: 10 },
{ _id: 1, host: "mongo-1.mongo-svc:27017", priority: 5 },
{ _id: 2, host: "mongo-2.mongo-svc:27017", priority: 5 }
],
settings: {
electionTimeoutMillis: 10000,
heartbeatTimeoutSecs: 10,
chainingAllowed: true
}
})
# Check replica set status
rs.status()
# Step down the primary (for maintenance)
rs.stepDown(60) // step down for 60 seconds
# Force reconfiguration (emergency)
rs.reconfig(newConfig, { force: true })Preferencia de lectura y preocupación de escritura
Preferencia de lecturacontrola dónde el controlador envía operaciones de lectura. Las opciones son:
primary: todas las lecturas van al primario. Consistencia más fuerte pero sin escala de lectura.primaryPreferred: las lecturas van al primario a menos que no esté disponible, luego al secundario.secondary: todas las lecturas van a secundarias. Proporciona escala de lectura pero puede devolver datos obsoletos.secondaryPreferred: las lecturas van a los secundarios a menos que no haya ninguno disponible.nearest: las lecturas van al miembro con la latencia de red más baja, independientemente de su función. Lo mejor para implementaciones distribuidas geográficamente.
Problema de escrituracontrola cuántos miembros del conjunto de réplicas deben confirmar una escritura antes de que la operación regrese al cliente.
w: 1: solo el principal debe confirmar. Es el más rápido, pero corre el riesgo de perder datos si el principal falla antes de la replicación.w: "majority": la mayoría de los miembros que poseen datos deben reconocerlo. Este es el valor predeterminado de producción recomendado. Garantiza que la escritura sobreviva a una elección primaria.w: <number>: un número específico de miembros debe confirmar.j: true: la escritura debe confirmarse en el diario en disco antes del reconocimiento. Combinado conw: "majority", esto proporciona la garantía de durabilidad más sólida.
# Connection string with write concern and read preference
mongodb://mongo-0:27017,mongo-1:27017,mongo-2:27017/appdb?replicaSet=rs-production&w=majority&j=true&readPreference=secondaryPreferred&readPreferenceTags=region:us-east
# SRV connection string (DNS-based discovery)
mongodb+srv://appuser:password@cluster.example.com/appdb?w=majority&retryWrites=true&readPreference=nearestMongoDB Arquitectura de clúster fragmentado
Un conjunto de réplicas proporciona alta disponibilidad pero no escalamiento de escritura horizontal: todas las escrituras van a un único primario. Cuando su conjunto de datos excede la capacidad de un único servidor o su rendimiento de escritura excede lo que un servidor principal puede manejar, necesita fragmentación. Un clúster fragmentado distribuye datos entre múltiples conjuntos de réplicas (fragmentos) mediante una clave de fragmento, lo que permite el escalamiento horizontal tanto del almacenamiento como del rendimiento de escritura.
Un clúster fragmentado tiene tres tipos de componentes. Los enrutadoresmongosson enrutadores de consultas sin estado que dirigen las operaciones del cliente a los fragmentos apropiados. Implemente al menos dos para lograr redundancia. Los servidores de configuraciónforman un conjunto de réplicas que almacena los metadatos del clúster: qué fragmentos viven en qué fragmentos, los rangos de claves de fragmentos y el estado del equilibrador. Los servidores de fragmentosson conjuntos de réplicas y cada uno de ellos contiene un subconjunto de datos fragmentados.
Selección de clave de fragmento
La clave de fragmentación es la decisión más importante en un clúster fragmentado. Determina cómo se distribuyen los datos entre fragmentos e impacta directamente en el rendimiento de las consultas, la distribución de escritura y la capacidad de escalar. Una buena clave de fragmento tiene una cardinalidad alta (muchos valores distintos), distribuye las escrituras de manera uniforme entre fragmentos y admite los patrones de consulta más comunes con operaciones específicas en lugar de recopilación dispersa.
# Enable sharding on a database
sh.enableSharding("appdb")
# Shard a collection with a hashed shard key (even distribution)
sh.shardCollection("appdb.events", { "event_id": "hashed" })
# Shard with a ranged shard key (supports range queries)
sh.shardCollection("appdb.orders", { "customer_id": 1, "order_date": 1 })
# Check shard distribution
db.orders.getShardDistribution()
# View chunk distribution across shards
use config
db.chunks.aggregate([
{ $group: { _id: "$shard", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
])Las estrategias de clave de partición comunes incluyen:claves hashpara una distribución de escritura uniforme (mejor cuando no necesita consultas de rango en la clave de partición),claves compuestasque combinan un campo de agrupación aproximado con un campo de alta cardinalidad (por ejemplo,{ tenant_id: 1, _id: 1 }para aplicaciones multiinquilino) ybasado en zonas clavesque alinean la ubicación de datos con las regiones geográficas.
para múltiples regiones
La fragmentación de zonarestringe rangos específicos de la clave de partición a fragmentos específicos, lo que permite la localidad de datos. Por ejemplo, puede garantizar que los datos de los clientes europeos se encuentren en fragmentos de la región de la UE, mientras que los datos de los clientes de EE. UU. se encuentren en fragmentos de la región de EE. UU.
# Add shards to zones
sh.addShardTag("shard-us-east", "US")
sh.addShardTag("shard-eu-west", "EU")
sh.addShardTag("shard-ap-south", "APAC")
# Define zone ranges
sh.addTagRange("appdb.customers",
{ "region": "US", "customer_id": MinKey },
{ "region": "US", "customer_id": MaxKey },
"US"
)
sh.addTagRange("appdb.customers",
{ "region": "EU", "customer_id": MinKey },
{ "region": "EU", "customer_id": MaxKey },
"EU"
)
sh.addTagRange("appdb.customers",
{ "region": "APAC", "customer_id": MinKey },
{ "region": "APAC", "customer_id": MaxKey },
"APAC"
)
# Verify zone configuration
sh.status()Implementación MongoDB multirregional
La distribución de MongoDB en varias regiones tiene dos propósitos: recuperación ante desastres (sobrevivir a la pérdida de una región completa) y optimización de la latencia (ofrecer lecturas desde la réplica más cercana). MongoDB admite implementaciones en varias regiones a través de miembros del conjunto de réplicas distribuidos entre regiones, fragmentación de zonas para la localidad de datos y configuración de preferencias de lectura que enruta las lecturas al miembro más cercano.
En un conjunto de réplicas de cinco miembros distribuidos en tres regiones (2 en la región primaria, 2 en la región DR, 1 en la región de lectura), la pérdida de la región primaria aún deja tres miembros disponibles, suficientes para que una mayoría elija una nueva primaria. El miembro de la región de lectura debe tenerpriority: 0para evitar que se convierta en principal (una latencia alta entre regiones degradaría el rendimiento de escritura). Utilicehidden: truepara miembros dedicados al análisis que no deberían recibir lecturas periódicas de la aplicación.
MongoDB Comunidad Kubernetes Operador
El operador Kubernetes de la comunidad MongoDB implementa y administra conjuntos de réplicas MongoDB en Kubernetes. Es el operador de código abierto de MongoDB Inc. que maneja la administración de StatefulSet, la configuración automatizada del conjunto de réplicas, la rotación de certificados TLS, la administración de usuarios y las actualizaciones continuas.
# Install the MongoDB Community Operator via Helm
helm repo add mongodb https://mongodb.github.io/helm-charts
helm repo update
helm install community-operator mongodb/community-operator \
--namespace mongodb \
--create-namespace \
--set operator.watchNamespace="*"MongoDBComunidad CRD Especificación
El recurso personalizadoMongoDBCommunitydefine el estado deseado de un conjunto de réplicas MongoDB. A continuación se muestra una especificación lista para producción.
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
name: production-mongodb
namespace: databases
spec:
members: 3
type: ReplicaSet
version: "7.0.12"
security:
authentication:
modes: ["SCRAM"]
tls:
enabled: true
certificateKeySecretRef:
name: mongodb-tls-cert
caCertificateSecretRef:
name: mongodb-ca-cert
users:
- name: appuser
db: admin
passwordSecretRef:
name: mongodb-appuser-password
roles:
- name: readWrite
db: appdb
- name: clusterMonitor
db: admin
scramCredentialsSecretName: appuser-scram
- name: backup-user
db: admin
passwordSecretRef:
name: mongodb-backup-password
roles:
- name: backup
db: admin
- name: restore
db: admin
scramCredentialsSecretName: backup-scram
- name: monitoring
db: admin
passwordSecretRef:
name: mongodb-monitoring-password
roles:
- name: clusterMonitor
db: admin
scramCredentialsSecretName: monitoring-scram
additionalMongodConfig:
storage.wiredTiger.engineConfig.cacheSizeGB: 4
storage.wiredTiger.engineConfig.journalCompressor: snappy
storage.wiredTiger.collectionConfig.blockCompressor: snappy
net.maxIncomingConnections: 10000
operationProfiling.mode: slowOp
operationProfiling.slowOpThresholdMs: 100
replication.oplogSizeMB: 51200
setParameter.cursorTimeoutMillis: 600000
statefulSet:
spec:
template:
spec:
containers:
- name: mongod
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
cpu: "4"
memory: 16Gi
- name: mongodb-agent
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: topology.kubernetes.io/zone
labelSelector:
matchLabels:
app: production-mongodb-svc
tolerations:
- key: "workload"
operator: "Equal"
value: "database"
effect: "NoSchedule"
volumeClaimTemplates:
- metadata:
name: data-volume
spec:
storageClassName: gp3-csi
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Gi
- metadata:
name: logs-volume
spec:
storageClassName: gp3-csi
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10GiEsta especificación crea un conjunto de réplicas de tres miembros que ejecuta MongoDB 7.0 con autenticación SCRAM, cifrado TLS, volúmenes de registros y datos separados, antiafinidad de pods en zonas de disponibilidad y ajuste WiredTiger apropiado para un nodo con 16 GB de RAM. El operador maneja la inicialización del conjunto de réplicas, la configuración de miembros y las actualizaciones continuas cuando cambia el campoversion.
Servidor Percona para Operador MongoDB
El operador Percona para MongoDB (operador PSMDB) proporciona una alternativa con más funciones al operador comunitario. Implementa Percona Server para MongoDB (un reemplazo directo para MongoDB con funciones empresariales adicionales), administra clústeres fragmentados y conjuntos de réplicas, integra la copia de seguridad a través de Percona Backup para MongoDB (PBM) y admite la recuperación en un momento dado.
# Install Percona Operator
helm repo add percona https://percona.github.io/percona-helm-charts/
helm repo update
helm install psmdb-operator percona/psmdb-operator \
--namespace psmdb \
--create-namespace# Percona Server for MongoDB Cluster CRD
apiVersion: psmdb.percona.com/v1
kind: PerconaServerMongoDB
metadata:
name: production-psmdb
namespace: databases
spec:
crVersion: "1.16.0"
image: percona/percona-server-mongodb:7.0.12-7
imagePullPolicy: IfNotPresent
replsets:
- name: rs0
size: 3
resources:
requests:
cpu: "2"
memory: 8Gi
limits:
cpu: "4"
memory: 16Gi
volumeSpec:
persistentVolumeClaim:
storageClassName: gp3-csi
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 100Gi
nonvoting:
enabled: false
arbiter:
enabled: false
configuration: |
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 4
journalCompressor: snappy
collectionConfig:
blockCompressor: snappy
operationProfiling:
mode: slowOp
slowOpThresholdMs: 100
replication:
oplogSizeMB: 51200
affinity:
antiAffinityTopologyKey: topology.kubernetes.io/zone
sharding:
enabled: false
mongos: {}
configsrv: {}
backup:
enabled: true
image: percona/percona-backup-mongodb:2.5.0
storages:
s3-backup:
type: s3
s3:
bucket: company-mongodb-backups
region: us-east-1
credentialsSecret: aws-s3-credentials
prefix: production
insecureSkipTLSVerify: false
pitr:
enabled: true
oplogOnly: false
compressionType: gzip
tasks:
- name: daily-full
enabled: true
schedule: "0 3 * * *"
keep: 7
storageName: s3-backup
compressionType: gzip
secrets:
users: mongodb-users-secret
pmm:
enabled: true
image: percona/pmm-client:2
serverHost: pmm-server.monitoringLa ventaja clave del Operador Percona es su gestión de respaldo integrada con Percona Backup para MongoDB (PBM). PBM admite copias de seguridad lógicas y físicas, copias de seguridad incrementales y recuperación en un momento dado desde el registro de operaciones, todo configurado de forma declarativa a través del CRD.
Implementación deAWS: DocumentDB frente a Atlas frente a autoadministrado en EKS
Amazon DocumentDBes un servicio de base de datos de documentos compatible con MongoDB. No es MongoDB, es un motor propietario que implementa el protocolo de conexión MongoDB (compatible hasta MongoDB 4.0 API). DocumentDB separa la computación del almacenamiento mediante una capa de almacenamiento distribuido similar a Aurora. Proporciona conmutación por error automática dentro de una región, hasta 15 réplicas de lectura y recuperación en un momento dado. Sin embargo, carece de muchas características de MongoDB: los flujos de cambios tienen limitaciones, las transacciones funcionan de manera diferente y muchas etapas del proceso de agregación no son compatibles. Utilice DocumentDB solo si su aplicación utiliza un subconjunto de API de MongoDB y valora la simplicidad operativa de un servicio totalmente administrado.
MongoDB Atlas en AWSes el servicio administrado propio de MongoDB que se ejecuta en la infraestructura AWS. Proporciona MongoDB genuino con todas las funciones, alta disponibilidad automatizada, copias de seguridad continuas, recuperación en un momento dado, escalamiento automático y clústeres multirregionales. Atlas es el camino más fácil hacia la producción de MongoDB, pero la opción más cara a escala.
Autoadministrado en EKSle brinda control total sobre la versión, la configuración y el costo de MongoDB. Utilice el operador comunitario MongoDB o el operador Percona con almacenamiento EBS gp3 y roles IAM para cuentas de servicio (IRSA) para un acceso seguro a la copia de seguridad de S3.
# EBS StorageClass optimised for MongoDB
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3-csi
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "6000"
throughput: "250"
encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retain# IRSA for backup S3 access
eksctl create iamserviceaccount \
--name mongodb-backup-sa \
--namespace databases \
--cluster my-eks-cluster \
--attach-policy-arn arn:aws:iam::111122223333:policy/MongoDBBackupS3Policy \
--approveImplementación deAzure: Cosmos DB frente a Atlas frente a autoadministrado en AKS
Azure Cosmos DB para MongoDB (vCore)es la oferta nativa de Azure más cercana al MongoDB real. A diferencia del antiguo Cosmos DB API para MongoDB basado en RU, el modelo vCore ejecuta instancias reales del motor MongoDB en computación dedicada, lo que proporciona una alta compatibilidad con las características de MongoDB 6.0+, incluido el proceso de agregación completo, los flujos de cambios y las transacciones. Ofrece HA con redundancia de zona, recuperación en un momento dado y copias de seguridad automáticas.
MongoDB Atlas en Azureproporciona la misma experiencia MongoDB totalmente administrada que en AWS, ejecutándose en una infraestructura Azure con emparejamiento VNET, Azure Private Link e integración Azure AD.
Autoadministrado en AKSutiliza discos administrados Azure (se recomienda SSD Premium v2) con el operador MongoDB o Percona.
# Azure Premium SSD StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: azure-premium-mongodb
provisioner: disk.csi.azure.com
parameters:
skuName: Premium_LRS
cachingMode: None
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: RetainImplementación deGCP: Atlas en GCP versus autoadministrado en GKE
MongoDB Atlas en GCPse ejecuta en la infraestructura de Google Cloud con integraciones nativas de GCP: emparejamiento de VPC, Private Service Connect e integración de clúster de GKE. Atlas en GCP admite clústeres multirregionales que abarcan regiones de GCP con conmutación por error automática.
Autoadministrado en GKEutiliza disco SSD persistente con el operador MongoDB o Percona. GKE Workload Identity proporciona autenticación segura y sin clave para realizar copias de seguridad en GCS.
# GKE SSD StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: pd-ssd-mongodb
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-ssd
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: RetainMetal desnudo k3s/Rancher con Longhorn
Para soberanía de datos, cumplimiento u optimización de costos, MongoDB se ejecuta de manera efectiva en Kubernetes sin sistema operativo utilizando k3s con administración Rancher y almacenamiento distribuido Longhorn. Esta arquitectura elimina las dependencias de los proveedores de la nube y al mismo tiempo mantiene el mismo modelo de gestión basado en operadores.
Almacenamiento Longhorn para MongoDB
# Install Longhorn
helm repo add longhorn https://charts.longhorn.io
helm repo update
helm install longhorn longhorn/longhorn \
--namespace longhorn-system \
--create-namespace \
--set defaultSettings.defaultReplicaCount=3 \
--set defaultSettings.storageMinimalAvailablePercentage=15
# StorageClass for MongoDB on Longhorn
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: longhorn-mongo
provisioner: driver.longhorn.io
parameters:
numberOfReplicas: "3"
staleReplicaTimeout: "2880"
dataLocality: best-effort
fsType: xfs
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: RetainSe recomiendaXFS sobre ext4 para MongoDB en Linux. El motor de almacenamiento WiredTiger de MongoDB se beneficia de los patrones de asignación de XFS, particularmente para los archivos de datos y de diario. La replicación de tres vías de Longhorn proporciona redundancia a nivel de volumen además de la redundancia a nivel de conjunto de réplicas de MongoDB, lo que le brinda una defensa en profundidad contra fallas de almacenamiento.
MetalLB y servicios sin cabeza
# MetalLB IP Pool for MongoDB
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: mongo-pool
namespace: metallb-system
spec:
addresses:
- 192.168.1.220-192.168.1.225
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: mongo-l2
namespace: metallb-system
spec:
ipAddressPools:
- mongo-poolEl operador MongoDB crea un servicio sin cabeza que le da a cada módulo un nombre DNS estable (mongo-0.mongo-svc.databases.svc.cluster.local). Esto es esencial para el descubrimiento de miembros del conjunto de réplicas. Si necesita acceso externo, MetalLB asigna una IP enrutable a un servicio LoadBalancer frente a los enrutadores mongos (para clústeres fragmentados) o el primario (para conjuntos de réplicas).
Estrategias de copia de seguridad
MongoDB ofrece múltiples enfoques de respaldo, cada uno adecuado para diferentes escenarios.
mongodump / mongorestore
Copias de seguridad lógicas que exportan documentos BSON. Portátiles e inspeccionables por humanos, pero lentos para grandes conjuntos de datos y no admiten la recuperación en un momento dado por sí solos.
# Full logical backup with oplog for consistency
mongodump --uri="mongodb://backup-user:password@mongo-0:27017,mongo-1:27017,mongo-2:27017/appdb?replicaSet=rs-production&authSource=admin" \
--oplog \
--gzip \
--out=/backups/$(date +%Y%m%d-%H%M%S)
# Restore
mongorestore --uri="mongodb://admin:password@mongo-0:27017/?replicaSet=rs-production&authSource=admin" \
--oplogReplay \
--gzip \
/backups/20260412-030000/Copia de seguridad Percona para MongoDB (PBM)
PBM proporciona copias de seguridad físicas, copias de seguridad incrementales y recuperación en un momento dado. Es la herramienta de respaldo recomendada para MongoDB autoadministrado en producción.
# Configure PBM storage
pbm config --set storage.type=s3 \
--set storage.s3.bucket=company-mongodb-backups \
--set storage.s3.region=us-east-1 \
--set storage.s3.credentials.access-key-id=$AWS_ACCESS_KEY \
--set storage.s3.credentials.secret-access-key=$AWS_SECRET_KEY
# Full backup
pbm backup --type=logical --compression=gzip
# Physical backup (faster, requires WiredTiger)
pbm backup --type=physical --compression=gzip
# Incremental backup
pbm backup --type=incremental --base-snapshot=2026-04-12T03:00:00Z
# Point-in-time recovery
pbm restore --time="2026-04-12T09:30:00Z"
# List backups
pbm list
# Check backup status
pbm statusInstantáneas de la nube
En los proveedores de nube, las instantáneas de EBS (AWS), las instantáneas de disco administrado (Azure) y las instantáneas de disco persistentes (GCP) proporcionan copias de seguridad rápidas a nivel de almacenamiento. Combinados condb.fsyncLock()para lograr coherencia en un momento determinado, ofrecen los tiempos de copia de seguridad y restauración más rápidos para grandes conjuntos de datos.
# Kubernetes VolumeSnapshot for MongoDB
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: mongodb-snapshot-$(date +%Y%m%d)
namespace: databases
spec:
volumeSnapshotClassName: csi-snapclass
source:
persistentVolumeClaimName: data-volume-production-mongodb-0Recuperación en un momento dado basada en Oplog
El registro de operaciones permite la recuperación en un momento dado (PITR) cuando se combina con una copia de seguridad base. PBM archiva continuamente las entradas del registro de operaciones en el almacenamiento de respaldo. Para restaurar a un momento específico, PBM restaura la copia de seguridad base más reciente y luego reproduce las entradas del registro de operaciones hasta la marca de tiempo de destino. Esto se configura en el Operador Percona CRD a través de la secciónpitr.
para HA
La configuración adecuada de la cadena de conexión es fundamental para la resiliencia de las aplicaciones durante eventos de conmutación por error.
# Standard connection string with all replica set members
mongodb://appuser:password@mongo-0.mongo-svc:27017,mongo-1.mongo-svc:27017,mongo-2.mongo-svc:27017/appdb?replicaSet=rs-production&w=majority&j=true&readPreference=secondaryPreferred&retryWrites=true&retryReads=true&connectTimeoutMS=10000&socketTimeoutMS=30000&serverSelectionTimeoutMS=15000&maxPoolSize=100&minPoolSize=10
# SRV-based connection string (DNS discovery)
mongodb+srv://appuser:password@mongo-cluster.databases.svc.cluster.local/appdb?w=majority&retryWrites=true&readPreference=nearest
# For sharded clusters (connect through mongos)
mongodb://appuser:password@mongos-0:27017,mongos-1:27017/appdb?w=majority&retryWrites=true&readPreference=nearestParámetros de cadena de conexión clavepara HA:retryWrites=trueyretryReads=truehabilitan el reintento automático de operaciones que fallan durante la conmutación por error.w=majoritygarantiza que las escrituras sobrevivan a las elecciones primarias.serverSelectionTimeoutMScontrola cuánto tiempo espera el controlador para encontrar un servidor adecuado; configúrelo por encima del tiempo de elección esperado (al menos 15 segundos).maxPoolSizelimita el grupo de conexiones por mongos/miembro del conjunto de réplicas para evitar el agotamiento de la conexión.
Optimización de índices y rendimiento de consultas
Los índicesson la palanca principal para el rendimiento de las consultas MongoDB. Un índice faltante en un campo consultado con frecuencia obliga a realizar un escaneo de la colección que se degrada linealmente con el tamaño de los datos.
# Create compound index for common query pattern
db.orders.createIndex(
{ customer_id: 1, order_date: -1, status: 1 },
{ name: "idx_customer_orders", background: true }
)
# Partial index (only index documents matching a filter)
db.events.createIndex(
{ timestamp: 1 },
{ name: "idx_active_events", partialFilterExpression: { status: "active" } }
)
# TTL index for automatic document expiration
db.sessions.createIndex(
{ createdAt: 1 },
{ expireAfterSeconds: 86400, name: "idx_session_ttl" }
)
# Text index for search
db.products.createIndex(
{ name: "text", description: "text" },
{ weights: { name: 10, description: 5 }, name: "idx_product_search" }
)
# Analyze query performance
db.orders.find({ customer_id: "c123" }).sort({ order_date: -1 }).explain("executionStats")
# Find unused indexes
db.orders.aggregate([ { $indexStats: {} } ])Revise$indexStatsperiódicamente para identificar índices no utilizados que desperdician almacenamiento y ralentizan las escrituras. Utilice el métodoexplain()para verificar que las consultas utilicen el índice esperado y verifique si hay untotalDocsExaminedalto en relación connReturned, lo que indica un plan de consulta ineficiente.
Ajuste del motor de almacenamiento WiredTiger
WiredTiger es el motor de almacenamiento de producción predeterminado y único de MongoDB desde MongoDB 4.2. Sus características de rendimiento están fuertemente influenciadas por el tamaño de la caché, la compresión y la configuración del diario.
# WiredTiger configuration in mongod.conf
storage:
dbPath: /data/db
journal:
enabled: true
commitIntervalMs: 100
wiredTiger:
engineConfig:
cacheSizeGB: 4 # ~50% of (RAM - 1GB), max 80%
journalCompressor: snappy
directoryForIndexes: true # separate dir for index files
collectionConfig:
blockCompressor: snappy # or zstd for better ratio
indexConfig:
prefixCompression: true
operationProfiling:
mode: slowOp
slowOpThresholdMs: 100
replication:
oplogSizeMB: 51200 # 50 GB oplog
replSetName: rs-production
net:
maxIncomingConnections: 10000
compression:
compressors: snappy,zstd,zlib
setParameter:
wiredTigerConcurrentReadTransactions: 128
wiredTigerConcurrentWriteTransactions: 128La caché de WiredTiger debe tener un tamaño adecuado para contener su conjunto de trabajo: los datos y los índices a los que acceden activamente sus consultas. Si el caché es demasiado pequeño, WiredTiger desaloja páginas con frecuencia, lo que provoca una alta E/S. Si es demasiado grande, deja memoria insuficiente para el caché del sistema de archivos del sistema operativo y otros procesos. Un punto de partida es el 50 % de la RAM disponible menos 1 GB (para el sistema operativo y otros procesos), limitado al tamaño del conjunto de trabajo.
Autenticacióny cifrado TLS
# Generate TLS certificates for MongoDB
# CA certificate
openssl req -x509 -newkey rsa:4096 -days 3650 -nodes \
-keyout ca.key -out ca.crt \
-subj "/CN=MongoDB-CA"
# Server certificate (include all member hostnames in SAN)
openssl req -newkey rsa:4096 -nodes \
-keyout server.key -out server.csr \
-subj "/CN=mongo-0.mongo-svc.databases.svc.cluster.local" \
-addext "subjectAltName=DNS:mongo-0.mongo-svc.databases.svc.cluster.local,DNS:mongo-1.mongo-svc.databases.svc.cluster.local,DNS:mongo-2.mongo-svc.databases.svc.cluster.local,DNS:localhost,IP:127.0.0.1"
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 365
# Combine cert and key into PEM
cat server.crt server.key > server.pem
# Create Kubernetes secrets
kubectl create secret tls mongodb-tls-cert \
--cert=server.crt --key=server.key -n databases
kubectl create secret generic mongodb-ca-cert \
--from-file=ca.crt=ca.crt -n databases# MongoDB TLS configuration (mongod.conf)
net:
tls:
mode: requireTLS
certificateKeyFile: /etc/mongodb/tls/server.pem
CAFile: /etc/mongodb/tls/ca.crt
allowConnectionsWithoutCertificates: false
security:
authorization: enabled
clusterAuthMode: x509Monitoreocon Prometheus y Grafana
MongoDB expone métricas a través delmongodb_exporter(de Percona) que se integra con Prometheus. Las métricas clave para monitorear incluyen recuentos de conexiones, tasas de operación, retraso de replicación, uso de caché de WiredTiger y eficiencia de orientación de consultas.
# Deploy mongodb_exporter as a sidecar or standalone
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-exporter
namespace: databases
spec:
replicas: 1
selector:
matchLabels:
app: mongodb-exporter
template:
metadata:
labels:
app: mongodb-exporter
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9216"
spec:
containers:
- name: exporter
image: percona/mongodb_exporter:0.40.0
args:
- --mongodb.uri=mongodb://monitoring:password@production-mongodb-0.production-mongodb-svc:27017,production-mongodb-1.production-mongodb-svc:27017,production-mongodb-2.production-mongodb-svc:27017/?replicaSet=rs-production&authSource=admin
- --collect-all
- --compatible-mode
ports:
- containerPort: 9216
resources:
requests:
cpu: 100m
memory: 128Mi# ServiceMonitor for Prometheus Operator
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: mongodb-metrics
namespace: databases
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app: mongodb-exporter
endpoints:
- port: metrics
interval: 15s
scrapeTimeout: 10s# Critical Prometheus alert rules for MongoDB
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: mongodb-alerts
namespace: databases
labels:
release: kube-prometheus-stack
spec:
groups:
- name: mongodb-health
rules:
- alert: MongoDBReplicationLagHigh
expr: mongodb_mongod_replset_member_replication_lag > 30
for: 5m
labels:
severity: warning
annotations:
summary: "MongoDB replica {{ $labels.name }} lag exceeds 30s"
- alert: MongoDBConnectionsHigh
expr: mongodb_connections{state="current"} / mongodb_connections{state="available"} > 0.8
for: 2m
labels:
severity: critical
annotations:
summary: "MongoDB connections above 80% capacity"
- alert: MongoDBWiredTigerCacheEvictions
expr: rate(mongodb_wiredtiger_cache_evicted_pages_total[5m]) > 100
for: 10m
labels:
severity: warning
annotations:
summary: "High WiredTiger cache eviction rate"
- alert: MongoDBReplicaSetNoPrimary
expr: mongodb_mongod_replset_number_of_members{state="PRIMARY"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "MongoDB replica set has no primary"
- alert: MongoDBQueryTargetingInefficient
expr: rate(mongodb_mongod_metrics_query_executor_total{state="scanned_objects"}[5m]) / rate(mongodb_mongod_metrics_query_executor_total{state="returned"}[5m]) > 100
for: 15m
labels:
severity: warning
annotations:
summary: "MongoDB scanning 100x more documents than returned"Cambio de flujos para aplicaciones en tiempo real
Los flujos de cambios proporcionan un mecanismo de notificación en tiempo real para cambios de datos en MongoDB. Aprovechan el oplog para enviar eventos de cambio a las aplicaciones, lo que permite arquitecturas basadas en eventos, paneles de control en tiempo real y canales de sincronización de datos sin sondeo.
// Watch changes on a collection
const pipeline = [
{ $match: { operationType: { $in: ["insert", "update", "replace"] } } },
{ $match: { "fullDocument.status": "active" } }
];
const changeStream = db.collection("orders").watch(pipeline, {
fullDocument: "updateLookup", // include full document on updates
resumeAfter: resumeToken // resume from last processed event
});
changeStream.on("change", (change) => {
console.log("Change detected:", change.operationType);
console.log("Document:", change.fullDocument);
// Store resume token for crash recovery
saveResumeToken(change._id);
});
changeStream.on("error", (error) => {
console.error("Change stream error:", error);
// Reconnect using saved resume token
});Las secuencias de cambios requieren un conjunto de réplicas o un clúster fragmentado (no funcionan en instancias mongod independientes). Sobreviven a las elecciones primarias: el conductor se vuelve a conectar automáticamente y reanuda la actividad desde el último token de reanudación recibido. Para uso en producción, conserve siempre el token de reanudación para que su aplicación pueda recuperarse de los reinicios sin perder eventos.
Mantenimiento continuo y actualizaciones de versión
MongoDB admite actualizaciones continuas en las que se actualiza un miembro del conjunto de réplicas a la vez, comenzando con los secundarios y terminando con el principal (lo que desencadena una reducción y una elección). Esto permite actualizaciones sin tiempo de inactividad para cambios de versión mayores y menores.
# Rolling upgrade procedure for self-managed replica set
# 1. Upgrade each secondary one at a time
# On secondary (mongo-2):
sudo systemctl stop mongod
sudo yum install -y mongodb-org-7.0.14 # or apt-get
sudo systemctl start mongod
# Wait for the member to reach SECONDARY state
rs.status()
# 2. Step down the primary
rs.stepDown()
# 3. Upgrade the old primary (now a secondary)
sudo systemctl stop mongod
sudo yum install -y mongodb-org-7.0.14
sudo systemctl start mongod
# 4. Verify cluster health
rs.status()
db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })
# 5. Set feature compatibility version (irreversible)
db.adminCommand({ setFeatureCompatibilityVersion: "7.0" })Con el operador comunitario MongoDB o el operador Percona en Kubernetes, las actualizaciones continuas son automáticas: simplemente actualice el campoversionen el CRD y el operador maneja la actualización continua de cada módulo, esperando que cada miembro se recupere antes de continuar.
Recuperación ante desastres y pruebas de conmutación por error
Una implementación de alta disponibilidad que nunca se ha probado en caso de error no se ha probado. Las pruebas periódicas de conmutación por error validan su arquitectura, sus alertas de monitoreo y los procedimientos de respuesta a incidentes de su equipo.
Pruebas de conmutación por error controladas# Test 1: Step down the primary
rs.stepDown(120) // 120-second election hold
// Monitor: election should complete in ~10-12s
// Verify: application reconnects and resumes operations
# Test 2: Kill a secondary pod in Kubernetes
kubectl delete pod production-mongodb-1 -n databases --grace-period=0 --force
// The StatefulSet recreates the pod
// The operator rejoins it to the replica set
# Test 3: Simulate network partition
kubectl exec production-mongodb-0 -n databases -- \
iptables -A INPUT -p tcp --dport 27017 -j DROP
// The isolated primary should step down (cannot reach majority)
// Remaining members elect a new primary
// Cleanup: remove iptables rule and let member rejoin
# Test 4: Simulate storage failure
kubectl exec production-mongodb-2 -n databases -- \
chmod 000 /data/db
// mongod should crash; Kubernetes restarts the pod
// The member resyncs from the primary's oplogQué medir durante la conmutación por error
- RTO (objetivo de tiempo de recuperación): tiempo desde el fallo primario hasta la nueva aceptación de escrituras primarias. Objetivo: menos de 30 segundos para conjuntos de réplicas.
- RPO (objetivo de punto de recuperación): pérdida de datos durante la conmutación por error. Con
w: majority, el RPO es cero para escrituras reconocidas. Conw: 1, RPO equivale al retraso de replicación en el momento del error. - Tasa de error de aplicación: porcentaje de solicitudes que fallan durante la ventana de conmutación por error. Con
retryWrites=true, la mayoría de los errores de escritura son reintentados automáticamente por el controlador. - Continuidad del flujo de cambios: verifique que los consumidores del flujo de cambios se reanuden desde su token guardado sin perder eventos.
- Fallo de un solo miembro: recuperación automática mediante el reinicio del pod Kubernetes y la puesta al día del registro de operaciones. No se requiere ninguna acción manual a menos que el miembro necesite una resincronización completa.
- Fallo primario: la elección automática promueve un secundario en 10 a 12 segundos. Verifique la conectividad de la aplicación y el retraso de replicación en los secundarios restantes.
- Fallo mayoritario: si la mayoría de los miembros están inactivos, el conjunto de réplicas pasa a ser de solo lectura (no es posible realizar elecciones). Restaure miembros o utilice
rs.reconfig({ force: true })como último recurso (esto puede provocar la pérdida de datos). - Pérdida completa del clúster: implemente un nuevo clúster, restaure desde la última copia de seguridad de PBM y reproduzca el registro de operaciones en el punto en el tiempo de destino. Actualice las cadenas de conexión y los registros DNS.
- Conmutación por error regional: si se pierde la región primaria, una secundaria en otra región se elige automáticamente como primaria (si tiene suficiente prioridad y los miembros restantes forman una mayoría). Actualice DNS para enrutar el tráfico a la nueva región principal.
Ajuste a nivel de sistema operativo
# Disable Transparent Huge Pages (critical for MongoDB)
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# Set readahead to 8-32 sectors for SSD
blockdev --setra 32 /dev/sda
# Increase file descriptor limits
ulimit -n 64000
ulimit -u 64000
# Swappiness
vm.swappiness = 1
# Dirty page ratio
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
# Network tuning
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_keepalive_time = 120Pautas para dimensionar recursos
- Caché WiredTiger: 50 % de la RAM disponible menos 1 GB, o el tamaño de su conjunto de trabajo, lo que sea menor.
- Tamaño de registro de operaciones: suficiente para realizar entre 24 y 72 horas de operaciones de escritura. Comience con 50 GB y monitoree con
rs.printReplicationInfo(). - IOPS de almacenamiento: MongoDB requiere muchas E/S, especialmente durante la compactación y los puntos de control. Utilice NVMe SSD o almacenamiento en la nube con IOPS aprovisionadas (gp3 con más de 6000 IOPS en AWS, Premium SSD v2 en Azure, pd-ssd en GCP).
- CPU: MongoDB se beneficia de múltiples núcleos para operaciones simultáneas de lectura/escritura, transacciones simultáneas de WiredTiger y tareas en segundo plano (puntos de control, compactación, replicación).
- Red: el tráfico de replicación puede ser significativo para cargas de trabajo con mucha escritura. Garantice una red de baja latencia y gran ancho de banda entre los miembros del conjunto de réplicas.
Gestión de conexión
# Application-side connection pool configuration
const client = new MongoClient(uri, {
maxPoolSize: 100,
minPoolSize: 10,
maxIdleTimeMS: 60000,
waitQueueTimeoutMS: 5000,
connectTimeoutMS: 10000,
socketTimeoutMS: 30000,
serverSelectionTimeoutMS: 15000,
retryWrites: true,
retryReads: true,
w: "majority",
readPreference: "secondaryPreferred",
compressors: ["snappy", "zstd"]
});Lista de verificación de monitoreo de- Retraso de replicación: alerta cuando algún secundario supera los 30 segundos de retraso.
- Saturación de conexión: alerta cuando las conexiones actuales superan el 80% de
maxIncomingConnections. - Caché WiredTiger: alerta cuando la proporción de llenado sucio de la caché supera el 20 % (indica que la presión de escritura excede el rendimiento del punto de control).
- Ventana de registro de operaciones: alerta cuando la ventana de registro de operaciones cae por debajo de 12 horas (riesgo de que los secundarios necesiten una resincronización completa después del mantenimiento).
- Consulta dirigida a: alerta cuando la proporción de documentos escaneados y documentos devueltos supera 100 (índice faltante).
- Uso del disco: alerta en los umbrales del 70 % y 85 %. MongoDB puede utilizar un espacio temporal significativo en el disco durante la compactación.
- Actualización de la copia de seguridad: alerta cuando la última copia de seguridad exitosa es anterior a su ventana de RPO.
- Disponibilidad de tickets: monitorea la lectura y escritura de tickets de WiredTiger. El agotamiento provoca colas de operaciones y picos de latencia.
# Replica set status
rs.status()
rs.conf()
rs.printReplicationInfo()
rs.printSecondaryReplicationInfo()
# Cluster health (sharded)
sh.status()
db.adminCommand({ balancerStatus: 1 })
db.adminCommand({ listShards: 1 })
# Server diagnostics
db.serverStatus()
db.currentOp({ "$all": true })
db.adminCommand({ hostInfo: 1 })
# Kill long-running operations
db.killOp(opId)
# Compaction (reclaim disk space)
db.runCommand({ compact: "orders" })
# Profiler (identify slow queries)
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(10)
# Index management
db.orders.getIndexes()
db.orders.createIndex({ field: 1 }, { background: true })
db.orders.dropIndex("index_name")
# Kubernetes-specific
kubectl get mongodbcommunity -n databases
kubectl describe mongodbcommunity production-mongodb -n databases
kubectl logs production-mongodb-0 -n databases -c mongod
kubectl exec -it production-mongodb-0 -n databases -c mongod -- mongoshMatriz de decisiones: elección de su arquitectura MongoDB HA
- Nube única, preferencia administrada: use MongoDB Atlas. Maneja HA, copias de seguridad, monitoreo y escalamiento con una sobrecarga operativa mínima.
- AWS con compatibilidad con MongoDB solo necesita: considere Amazon DocumentDB si su aplicación utiliza un subconjunto básico de MongoDB API y desea una experiencia completamente administrada. En caso contrario, Atlas o autogestionado en EKS.
- Azure con funciones completas de MongoDB: use Cosmos DB para MongoDB vCore para una experiencia administrada, o Atlas en Azure para el servicio administrado MongoDB genuino.
- Multinube o híbrido: autoadministrado con el operador comunitario MongoDB o el operador Percona. La abstracción Kubernetes permite una implementación consistente entre proveedores.
- Metal desnudo o borde— k3s + Rancher + Longhorn + MongoDB Operador comunitario u Operador Percona. No se requieren dependencias de la nube.
- Escalado horizontal a gran escala: clúster fragmentado con fragmentación de zonas para la localidad de datos. Utilice el operador Percona, que admite implementaciones fragmentadas de forma nativa.
- Aplicaciones controladas por eventos en tiempo real: los flujos de cambios MongoDB proporcionan CDC integrado. Asegúrese de utilizar un conjunto de réplicas o un clúster fragmentado (no independiente).
Conclusión
Las primitivas de replicación y fragmentación integradas deMongoDB le brindan una ventaja arquitectónica para una alta disponibilidad: los conjuntos de réplicas con conmutación por error automática y los clústeres fragmentados con escalamiento horizontal son capacidades nativas, no ideas posteriores. Pero estas primitivas deben configurarse correctamente y operarse con disciplina para ofrecer las garantías de disponibilidad que exigen los sistemas de producción.
Una implementación de MongoDB de producción requiere tres miembros del conjunto de réplicas que contienen datos en todos los dominios de falla, preocupación de escrituraw: majoritypor la durabilidad, tamaño adecuado del registro de operaciones para la resiliencia de la replicación, ajuste de caché de WiredTiger para su conjunto de trabajo y una estrategia de respaldo probada con capacidad de recuperación en un punto en el tiempo. Los operadores Kubernetes, ya sea el operador comunitario MongoDB para conjuntos de réplicas o el operador Percona para implementaciones con todas las funciones, incluida la fragmentación y las copias de seguridad integradas, automatizan la gestión del ciclo de vida que, de otro modo, requeriría una inversión operativa significativa.
Los patrones de implementación en AWS, Azure, GCP y bare metal comparten la misma configuración central de MongoDB. Lo que cambia es la clase de almacenamiento, el destino de la copia de seguridad y la capa de red. Esta coherencia es el valor de un enfoque basado en operadores: su equipo aprende una herramienta, un modelo operativo y un conjunto de runbooks que funcionan en todas partes.
Comience con un conjunto de réplicas de tres miembros, escriturasw: majority, una copia de seguridad PBM diaria con archivado continuo de registros de operaciones y las alertas principales Prometheus para retrasos en la replicación, saturación de conexiones y presión de caché. Pruebe su conmutación por error el primer día, no durante el primer incidente. Amplíe sus servicios a fragmentación, localidad de datos basada en zonas e implementaciones multirregionales a medida que crezcan sus requisitos de disponibilidad y volumen de datos. La infraestructura se encarga de la mecánica; su responsabilidad es comprender la arquitectura con suficiente profundidad para hacer las concesiones correctas para su carga de trabajo y probar esas suposiciones sin descanso.