Высокая доступность MongoDB в производстве: наборы реплик, сегментирование и операторы Kubernetes
MongoDB HA с наборами реплик, сегментированием и операторами Kubernetes
MongoDB занимает уникальное положение в сфере баз данных. Ее модель документа естественным образом сопоставляется с объектами приложения, ее гибкая схема учитывает развивающиеся структуры данных без миграции, а встроенные примитивы репликации и сегментирования обеспечивают основу для высокой доступности и горизонтального масштабирования, для достижения которых реляционные базы данных требуют внешних инструментов. Но фундамент – это не готовое здание. Запуск MongoDB в производственной среде с подлинно высокой доступностью — когда сбой узла, сетевой раздел или выход из строя всего региона не приводит к простою или потере данных — требует продуманной архитектуры, тщательной настройки и строгой эксплуатационной дисциплины.
В этом руководстве рассматриваются все уровни высокой доступности MongoDB: от протокола консенсуса набора реплик и репликации oplog, которые обеспечивают автоматическое переключение при сбое, через архитектуру сегментированного кластера, обеспечивающую горизонтальное масштабирование, до операторов Kubernetes, которые автоматизируют управление жизненным циклом, а также варианты развертывания на AWS, Azure, GCP и «голом железе» k3s с Rancher. Каждый раздел включает конкретную конфигурацию, манифесты YAML и рабочие процедуры, которые вы можете адаптировать к своей среде.
Архитектура набора реплик MongoDB
Набор реплик — это основной элемент обеспечения высокой доступности MongoDB. Это группа процессовmongod, которые поддерживают один и тот же набор данных. Одним из членовявляется основной, который получает все операции записи. Остальные члены являются вторичными узлами, которые реплицируют данные из первичного узла, отслеживая его журнал операций (oplog). Если первичный сервер становится недоступным, набор реплик проводит выборы для выбора нового первичного сервера из подходящих вторичных серверов — обычно в течение 10–12 секунд.
Рабочий набор реплик должен состоять как минимум из трех элементов, несущих данные, в идеале распределенных по разным доменам сбоев (зоны доступности, стойки или центры обработки данных). Это гарантирует, что набор реплик сможет пережить потерю любого отдельного участника и при этом сохранить большинство для целей выборов. Дополнительный арбитручаствует в выборах, но не содержит данных — он существует исключительно для разрыва связей, когда у вас есть четное количество элементов, несущих данные, хотя лучшая практика MongoDB — вместо этого использовать нечетное количество элементов, несущих данные.
Оплог и механика репликации
Оплог — это ограниченная коллекция (local.oplog.rs), которая записывает каждую операцию по изменению данных на первичном сервере в идемпотентной форме. Вторичные устройства постоянно следят за оплогом основного и выполняют операции локально. Размер операционного журнала определяет, насколько сильно отстает вторичный сервер, прежде чем ему потребуется полная повторная синхронизация — для производственных рабочих нагрузок размер операционного журнала должен обеспечивать как минимум 24–72 часа активности записи. MongoDB 4.4+ поддерживает динамическое определение размера oplog черезreplSetResizeOplog.
# 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()Выборы и протокол на плоту
MongoDB 4.0+ использует консенсусный протокол, основанный на Raft, для выборов набора реплик. Когда вторичный узел обнаруживает, что основной недоступен (electionTimeoutMillisпо умолчанию — 10 000 мс), он может объявить выборы. Для победы кандидат должен получить голоса большинства голосующих членов. Участник с самой последней записью в оплоге и наивысшим приоритетом побеждает, если право на участие имеют несколько кандидатов. Вы можете влиять на результаты выборов, устанавливая приоритеты участников — участник сpriority: 0никогда не сможет стать основным, что полезно для аналитических реплик или участников в удаленных регионах.
# 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 })Предпочтения чтения и проблемы с записью
Предпочтения чтенияуправляет тем, куда драйвер отправляет операции чтения. Возможные варианты:
.primary— Все операции чтения передаются на первичный порт. Высочайшая согласованность, но без масштабирования чтения.primaryPreferred— операции чтения выполняются на первичном устройстве, если оно недоступно, а затем на вторичном.secondary— Все операции чтения передаются во вторичные устройства. Обеспечивает масштабирование чтения, но может возвращать устаревшие данные.secondaryPreferred— операции чтения передаются на вторичные устройства, если они недоступны.nearest— операции чтения передаются участнику с наименьшей задержкой в сети независимо от роли. Лучше всего подходит для геораспределенных развертываний.
Записьконтролирует, сколько членов набора реплик должны подтвердить запись, прежде чем операция вернется к клиенту.
w: 1— Подтверждать должен только первичный преобразователь. Самый быстрый, но существует риск потери данных в случае сбоя основного сервера перед репликацией.w: "majority"— большинство элементов, несущих данные, должны подтвердить это. Это рекомендуемое производственное значение по умолчанию. Это гарантирует, что запись переживет первичные выборы.w: <number>— определенное количество участников должно подтвердить.j: true— запись должна быть зафиксирована в журнале на диске перед подтверждением. В сочетании сw: "majority"это обеспечивает максимальную гарантию долговечности.
# 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=nearestАрхитектура сегментированного кластера MongoDB
Набор реплик обеспечивает высокую доступность, но не горизонтальное масштабирование записи — все записи выполняются в один основной сервер. Когда ваш набор данных превышает емкость одного сервера или ваша пропускная способность записи превышает то, что может обработать один основной сервер, вам необходимо сегментирование. Сегментированный кластер распределяет данные по нескольким наборам реплик (осколкам) с помощью сегментного ключа, обеспечивая горизонтальное масштабирование как хранилища, так и пропускной способности записи.
Сегментированный кластер состоит из трех типов компонентов. Маршрутизаторыmongos— это маршрутизаторы запросов без сохранения состояния, которые направляют клиентские операции на соответствующие сегменты. Разверните как минимум два для обеспечения резервирования. Серверы конфигурацииобразуют набор реплик, в котором хранятся метаданные кластера — какие фрагменты живут на каких сегментах, диапазоны ключей сегментов и состояние балансировщика. Серверы сегментовпредставляют собой наборы реплик, каждый из которых содержит подмножество сегментированных данных.
Выбор сегментного ключа
Шард-ключ — наиболее важное решение в сегментированном кластере. Он определяет, как данные распределяются по сегментам, и напрямую влияет на производительность запросов, распределение записи и возможность масштабирования. Хороший сегментный ключ имеет высокую мощность (множество различных значений), равномерно распределяет записи по сегментам и поддерживает наиболее распространенные шаблоны запросов с целевыми операциями, а не с разбросом и сбором.
# 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 } }
])Общие стратегии сегментных ключей включают:хешированные ключидля равномерного распределения записи (лучше всего, если вам не нужны запросы диапазона для сегментного ключа), составные ключи, которые сочетают в себе поле грубой группировки с полем высокой мощности (например,{ tenant_id: 1, _id: 1 }для многопользовательских приложений) ина основе зон. ключи, которые согласовывают размещение данных с географическими регионами.
для нескольких регионов
Сегментирование зоныограничивает определенные диапазоны ключа сегмента конкретными сегментами, обеспечивая локальность данных. Например, вы можете гарантировать, что данные о клиентах из Европы будут храниться в сегментах в регионе ЕС, а данные о клиентах из США — в сегментах в регионе США.
# 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()Многорегиональное развертывание MongoDB
Распространение MongoDB по нескольким регионам служит двум целям: аварийное восстановление (после потери всего региона) и оптимизация задержки (обслуживание операций чтения из ближайшей реплики). MongoDB поддерживает развертывание в нескольких регионах с помощью членов набора реплик, распределенных по регионам, сегментирования зон для локальности данных и конфигурации предпочтений чтения, которая направляет чтение ближайшему участнику.
В наборе реплик из пяти участников, распределенном по трем регионам (2 в основном регионе, 2 в регионе DR, 1 в регионе чтения), потеря основного региона по-прежнему оставляет трех членов доступными — достаточно, чтобы большинство избрало нового основного региона. Член в регионе чтения должен иметьpriority: 0, чтобы он не стал основным (высокая межрегиональная задержка может снизить производительность записи). Используйтеhidden: trueдля участников, специализирующихся на аналитике, которым не требуется регулярное чтение приложений.
MongoDB Сообщество Kubernetes Оператор
Оператор Kubernetes сообщества MongoDB развертывает и управляет наборами реплик MongoDB на Kubernetes. Это оператор с открытым исходным кодом от MongoDB Inc., который занимается управлением StatefulSet, автоматической настройкой набора реплик, ротацией сертификатов TLS, управлением пользователями и чередующимися обновлениями.
# 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="*"MongoDBСпецификация сообщества CRD
Пользовательский ресурсMongoDBCommunityопределяет желаемое состояние набора реплик MongoDB. Ниже представлена готовая к производству спецификация.
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: 10GiЭта спецификация создает набор реплик из трех участников под управлением MongoDB 7.0 с аутентификацией SCRAM, шифрованием TLS, отдельными томами данных и журналов, антипривязкой модулей между зонами доступности и настройкой WiredTiger, подходящей для узла с 16 ГБ ОЗУ. Оператор управляет инициализацией набора реплик, настройкой участников и последовательными обновлениями при изменении поляversion.
Сервер Percona для оператора MongoDB
Оператор Percona для MongoDB (оператор PSMDB) представляет собой более многофункциональную альтернативу оператору сообщества. Он развертывает Percona Server для MongoDB (замена MongoDB с дополнительными корпоративными функциями), управляет сегментированными кластерами, а также наборами реплик, интегрирует резервное копирование через Percona Backup for MongoDB (PBM) и поддерживает восстановление на определенный момент времени.
# 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.monitoringКлючевым преимуществом Percona Оператора является интегрированное управление резервным копированием с помощью Percona Backup for MongoDB (PBM). PBM поддерживает логическое и физическое резервное копирование, инкрементальное резервное копирование и восстановление на определенный момент времени из журнала операций — все это настраивается декларативно через CRD.
Развертывание AWS: DocumentDB, Atlas и самостоятельное управление на EKS
Amazon DocumentDB— это служба базы данных документов, совместимая с MongoDB. Это не MongoDB — это запатентованный механизм, реализующий проводной протокол MongoDB (совместимый до MongoDB 4.0 API). DocumentDB отделяет вычисления от хранилища, используя уровень распределенного хранения, аналогичный Aurora. Он обеспечивает автоматическое переключение при сбое внутри региона, до 15 реплик чтения и восстановление на определенный момент времени. Однако ему не хватает многих функций MongoDB: потоки изменений имеют ограничения, транзакции работают по-другому, а многие этапы конвейера агрегации не поддерживаются. Используйте DocumentDB только в том случае, если ваше приложение использует подмножество API MongoDB и вы цените простоту эксплуатации полностью управляемого сервиса.
MongoDB Atlas на AWS— это собственная управляемая служба MongoDB, работающая в инфраструктуре AWS. Он обеспечивает подлинный MongoDB со всеми функциями, автоматизированной высокой доступностью, непрерывным резервным копированием, восстановлением на определенный момент времени, автоматическим масштабированием и кластерами с несколькими регионами. Atlas — это самый простой путь к производству MongoDB, но самый дорогой вариант в масштабе.
Самоуправляемый на EKSдает вам полный контроль над версией, конфигурацией и стоимостью MongoDB. Используйте оператора сообщества MongoDB или оператора Percona с хранилищем EBS gp3 и ролями IAM для учетных записей служб (IRSA) для безопасного доступа к резервному копированию 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 \
--approveРазвертывание Azure: Cosmos DB, Atlas и самостоятельное управление на AKS
Azure Cosmos DB для MongoDB (виртуальное ядро)— это самое близкое к реальному MongoDB предложение Azure. В отличие от более старой версии Cosmos DB API на базе RU для MongoDB, модель виртуального ядра запускает реальные экземпляры ядра MongoDB на выделенных вычислениях, обеспечивая высокую совместимость с функциями MongoDB 6.0+, включая полный конвейер агрегации, потоки изменений и транзакции. Он предлагает высокую доступность с резервированием зон, восстановление на определенный момент времени и автоматическое резервное копирование.
MongoDB Atlas на Azureобеспечивает те же полностью управляемые возможности MongoDB, что и на AWS, работая в инфраструктуре Azure с пирингом виртуальных сетей, Azure Private Link и интеграцией Azure AD.
с самоуправляемым управлением на AKSиспользует управляемые диски Azure (рекомендуется твердотельный накопитель премиум-класса версии 2) с оператором MongoDB или 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: RetainРазвертываниеGCP: Atlas на GCP и самостоятельное управление на GKE
MongoDB Atlas на GCPработает в инфраструктуре Google Cloud со встроенной интеграцией GCP: пиринг VPC, Private Service Connect и интеграция кластера GKE. Atlas on GCP поддерживает многорегиональные кластеры, охватывающие регионы GCP, с автоматическим переходом на другой ресурс.
Самоуправляемый на GKEиспользует SSD с постоянным диском с оператором MongoDB или Percona. GKE Workload Identity обеспечивает безопасную аутентификацию без ключа для резервного копирования в 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: RetainBare Metal k3s/Rancher с Longhorn
Для обеспечения суверенитета данных, соответствия требованиям или оптимизации затрат MongoDB эффективно работает на аппаратном процессоре Kubernetes с использованием k3s с управлением Rancher и распределенным хранилищем Longhorn. Эта архитектура устраняет зависимости от поставщиков облачных услуг, сохраняя при этом ту же модель управления на уровне оператора.
Система хранения данных Longhorn для 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: RetainXFS рекомендуется использовать вместо ext4 для MongoDB в Linux. Механизм хранения WiredTiger MongoDB использует шаблоны распределения XFS, особенно для файлов журналов и данных. Трехсторонняя репликация Longhorn обеспечивает избыточность на уровне тома в дополнение к избыточности на уровне набора реплик MongoDB, обеспечивая глубокую защиту от сбоев хранилища.
MetalLB и автономные сервисы
# 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-poolОператор MongoDB создает автономную службу, которая присваивает каждому модульу стабильное имя DNS (mongo-0.mongo-svc.databases.svc.cluster.local). Это важно для обнаружения членов набора реплик. Если вам нужен внешний доступ, MetalLB назначает маршрутизируемый IP-адрес службе LoadBalancer перед маршрутизаторами mongos (для сегментированных кластеров) или основным (для наборов реплик).
Стратегии резервного копирования
MongoDB предлагает несколько подходов к резервному копированию, каждый из которых подходит для разных сценариев.
mongodump / mongorestore
Логические резервные копии, экспортирующие документы BSON. Портативный и легко проверяемый человеком, но медленный для больших наборов данных и не поддерживает самостоятельное восстановление на определенный момент времени.
# 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/Резервное копирование Percona для MongoDB (PBM)
PBM обеспечивает физическое резервное копирование, инкрементное резервное копирование и восстановление на определенный момент времени. Это рекомендуемый инструмент резервного копирования для автономного управления MongoDB в производственной среде.
# 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 statusОблачные снимки
У облачных провайдеров снимки EBS (AWS), снимки управляемых дисков (Azure) и постоянные снимки дисков (GCP) обеспечивают быстрое резервное копирование на уровне хранилища. В сочетании сdb.fsyncLock(), обеспечивающим согласованность на определенный момент времени, они обеспечивают максимально быстрое резервное копирование и восстановление больших наборов данных.
# 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-0Восстановление на определенный момент времени на основе Oplog
Oplog обеспечивает восстановление на определенный момент времени (PITR) в сочетании с базовой резервной копией. PBM постоянно архивирует записи oplog в хранилище резервных копий. Для восстановления на определенный момент времени PBM восстанавливает самую последнюю базовую резервную копию, а затем воспроизводит записи журнала операций до целевой отметки времени. Это настраивается в Percona Оператор CRD через разделpitr.
для HA
Правильная конфигурация строки подключения имеет решающее значение для устойчивости приложения во время аварийного переключения.
# 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=nearestКлючевые параметры строки подключения для высокой доступности:retryWrites=trueиretryReads=trueпозволяют автоматически повторять операции, которые завершаются сбоем во время переключения при сбое.w=majorityгарантирует, что запись выдержит первичные выборы.serverSelectionTimeoutMSконтролирует время ожидания драйвером поиска подходящего сервера — установите его выше ожидаемого времени выбора (не менее 15 секунд).maxPoolSizeограничивает пул соединений для каждого члена набора mongos/реплик, чтобы предотвратить исчерпание соединений.
Оптимизация индекса и производительность запросов
Индексы— это основной рычаг повышения производительности запросов MongoDB. Отсутствие индекса в часто запрашиваемом поле приводит к сканированию коллекции, которое ухудшается линейно с размером данных.
# 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: {} } ])Регулярно проверяйте$indexStats, чтобы выявить неиспользуемые индексы, которые тратят память и замедляют запись. Используйте методexplain(), чтобы убедиться, что запросы используют ожидаемый индекс, и проверьте высокий уровеньtotalDocsExaminedотносительноnReturned, что указывает на неэффективный план запроса.
Настройка механизма хранения данных WiredTiger
WiredTiger — это механизм хранения данных MongoDB по умолчанию и единственный, начиная с MongoDB 4.2. На его производительность сильно влияют размер кэша, сжатие и конфигурация журнала.
# 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: 128Размер кэша WiredTiger должен соответствовать размеру вашего рабочего набора — данных и индексов, к которым активно обращаются ваши запросы. Если кэш слишком мал, WiredTiger часто удаляет страницы, что приводит к увеличению количества операций ввода-вывода. Если он слишком велик, остается недостаточно памяти для кэша файловой системы ОС и других процессов. Отправной точкой является 50% доступной оперативной памяти минус 1 ГБ (для ОС и других процессов), ограниченный размером рабочего набора.
Аутентификацияи шифрование 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: x509Мониторинг с помощью Prometheus и Grafana
MongoDB предоставляет метрики черезmongodb_exporter(от Percona), который интегрируется с Prometheus. Ключевые показатели для мониторинга включают количество подключений, скорость операций, задержку репликации, использование кэша WiredTiger и эффективность таргетинга запросов.
# 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"Потоки изменения для приложений реального времени
Потоки изменений обеспечивают механизм уведомления в реальном времени об изменениях данных в MongoDB. Они используют oplog для передачи событий изменений в приложения, обеспечивая создание управляемых событиями архитектур, информационных панелей в реальном времени и конвейеров синхронизации данных без опроса.
// 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
});Потоки изменений требуют набора реплик или сегментированного кластера (они не работают на автономных экземплярах mongod). Они выдерживают первичные выборы — драйвер автоматически переподключается и возобновляет работу с последнего полученного токена возобновления. При использовании в рабочей среде всегда сохраняйте токен возобновления, чтобы приложение могло восстанавливаться после перезапуска без пропуска событий.
Постоянное обслуживание и обновлениеMongoDB поддерживает последовательные обновления, при которых вы обновляете по одному члену набора реплик за раз, начиная со вторичных и заканчивая основным (что приводит к понижению уровня и выбору). Это позволяет выполнять обновления без простоев при незначительных и основных изменениях версий.
# 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" })С помощью оператора сообщества MongoDB или оператора Percona на Kubernetes последовательные обновления автоматизированы: вы просто обновляете полеversionв CRD, и оператор выполняет последовательное обновление каждого модуля, ожидая, пока каждый участник станет работоспособным, прежде чем продолжить.
Тестирование аварийного восстановления и переключения при сбое
Развертывание высокой доступности, которое никогда не тестировалось на отказ, не тестируется. Регулярное тестирование аварийного переключения проверяет вашу архитектуру, оповещения мониторинга и процедуры реагирования на инциденты вашей команды.
Тесты управляемого переключения при отказе
# 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 oplogЧто измерять во время аварийного переключения
- RTO (целевое время восстановления)— время от первичного сбоя до нового первичного приема записи. Цель: менее 30 секунд для наборов реплик.
- RPO (целевая точка восстановления)— потеря данных во время аварийного переключения. В случае
w: majorityRPO равно нулю для подтвержденных операций записи. В случаеw: 1RPO равен задержке репликации во время сбоя. - Частота ошибок приложений— процент запросов, которые завершились сбоем во время окна переключения при сбое. При использовании
retryWrites=trueбольшинство ошибок записи автоматически повторяются драйвером. - Изменение непрерывности потока— убедитесь, что потребители потока изменений возобновляют работу со своим сохраненным маркером без пропуска событий.
Runbook для аварийного восстановления
- Сбой одного участника— автоматическое восстановление посредством перезапуска модуля Kubernetes и восстановления работоспособности журнала. Никаких действий вручную не требуется, если участнику не требуется полная повторная синхронизация.
- Сбой первичного устройства— автоматические выборы повышают вторичное значение в течение 10–12 секунд. Проверьте подключение приложений и задержку репликации на остальных вторичных серверах.
- Ошибка большинства.— если большинство участников отключено, набор реплик становится доступным только для чтения (выборы невозможны). Восстановите участников или используйте
rs.reconfig({ force: true })в крайнем случае (это может привести к потере данных). - Полная потеря кластера— разверните новый кластер, восстановите его из последней резервной копии PBM и воспроизведите операционный журнал до целевого момента времени. Обновите строки подключения и записи DNS.
- Региональное аварийное переключение— если основной регион потерян, дополнительный регион в другом регионе автоматически избирается основным (если он имеет достаточный приоритет и остальные участники составляют большинство). Обновите DNS, чтобы направить трафик в новый основной регион.
Настройка на уровне ОС
# 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 = 120Рекомендации по определению размера ресурсов- Кэш WiredTiger: 50 % доступной оперативной памяти минус 1 ГБ или размер вашего рабочего набора, в зависимости от того, что меньше.
- Размер Oplog: Достаточный для хранения операций записи в течение 24–72 часов. Начните с 50 ГБ и мониторьте с помощью
rs.printReplicationInfo(). - IOPS хранилища: MongoDB требует большого количества операций ввода-вывода, особенно во время уплотнения и создания контрольных точек. Используйте твердотельный накопитель NVMe или облачное хранилище с выделенным числом операций ввода-вывода в секунду (gp3 с более чем 6000 операций ввода-вывода в секунду на AWS, твердотельный накопитель Premium v2 на Azure, pd-ssd на GCP).
- CPU: MongoDB использует несколько ядер для одновременных операций чтения/записи, параллельных транзакций WiredTiger и фоновых задач (постановка контрольных точек, сжатие, репликация).
- Сеть: Трафик репликации может быть значительным для рабочих нагрузок с большим объемом записи. Обеспечьте сетевое соединение с низкой задержкой и высокой пропускной способностью между участниками набора реплик.
Управление соединениями
# 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"]
});Контрольный список мониторинга- Задержка репликации— оповещение, когда задержка любого вторичного сервера превышает 30 секунд.
- Насыщенность соединения— предупреждение, когда ток соединения превышает 80% от
maxIncomingConnections. - Кэш WiredTiger— выдает предупреждение, когда коэффициент заполнения кэша превышает 20 % (указывает, что давление записи превышает пропускную способность контрольной точки).
- Окно операционного журнала— оповещение, когда окно операционного журнала опускается ниже 12 часов (риск того, что вторичным узлам потребуется полная повторная синхронизация после обслуживания).
- Запрос, нацеленный на— предупреждение, когда соотношение отсканированных документов к возвращенным документам превышает 100 (отсутствует индекс).
- Использование диска— оповещение при пороговых значениях 70 % и 85 %. MongoDB может использовать значительный объем временного дискового пространства во время сжатия.
- Свежесть резервной копии— оповещение, когда последняя успешная резервная копия старше вашего окна RPO.
- Доступность билетов— мониторинг чтения и записи билетов WiredTiger. Исчерпание вызывает появление очередей операций и резкие скачки задержек.
Краткое руководство по рабочим командам
# 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 -- mongoshМатрица решений: выбор архитектуры высокой доступности MongoDB
- Единое облако, управляемые предпочтения— используйте MongoDB Atlas. Он обеспечивает высокую доступность, резервное копирование, мониторинг и масштабирование с минимальными эксплуатационными расходами.
- AWS с MongoDB-совместимым требуется только. Рассмотрите возможность использования Amazon DocumentDB, если ваше приложение использует базовое подмножество MongoDB API и вам нужна полностью управляемая среда. В противном случае Атлас или самоуправление на ЭКС.
- Azure с полными функциями MongoDB— используйте Cosmos DB для виртуального ядра MongoDB для управляемого взаимодействия или Atlas на Azure для подлинной управляемой службы MongoDB.
- Мультиоблачная или гибридная система— самостоятельное управление с помощью оператора сообщества MongoDB или оператора Percona. Абстракция Kubernetes обеспечивает согласованное развертывание между поставщиками.
- Голый металл или край— k3s + Rancher + Longhorn + Оператор сообщества MongoDB или Оператор Percona. Никаких облачных зависимостей не требуется.
- Крупномасштабное горизонтальное масштабирование— сегментированный кластер с сегментированием зон для локальности данных. Используйте оператор Percona, который изначально поддерживает сегментированное развертывание.
- Приложения, управляемые событиями в реальном времени.— потоки изменений MongoDB обеспечивают встроенный CDC. Убедитесь, что вы используете набор реплик или сегментированный кластер (не автономный).
Заключение
Встроенные примитивы репликации и сегментированияMongoDB дают ему архитектурное преимущество, обеспечивающее высокую доступность: наборы реплик с автоматическим аварийным переключением и сегментированные кластеры с горизонтальным масштабированием — это встроенные возможности, а не прикрученные второстепенные мысли. Но эти примитивы должны быть правильно настроены и дисциплинированно эксплуатироваться, чтобы обеспечить гарантии доступности, которых требуют производственные системы.
Для производственного развертывания MongoDB требуются три элемента набора реплик, несущих данные, в доменах сбоев, забота о записиw: majorityдля обеспечения надежности, правильный размер oplog для устойчивости репликации, настройка кэша WiredTiger для вашего рабочего набора и проверенная стратегия резервного копирования с возможностью восстановления на определенный момент времени. Операторы Kubernetes — будь то оператор сообщества MongoDB для наборов реплик или оператор Percona для полнофункциональных развертываний, включая сегментирование и интегрированное резервное копирование — автоматизируют управление жизненным циклом, которое в противном случае потребовало бы значительных операционных инвестиций.
Схемы развертывания AWS, Azure, GCP и «голого железа» используют одну и ту же базовую конфигурацию MongoDB. Что меняется, так это класс хранилища, место назначения резервного копирования и сетевой уровень. Такая согласованность является ценностью операторского подхода: ваша команда изучает один инструмент, одну операционную модель и один набор модулей Runbook, которые работают повсюду.
Начните с набора реплик из трех элементов, пишетw: majority, ежедневного резервного копирования PBM с непрерывным архивированием oplog и оповещений ядра Prometheus о задержке репликации, насыщении соединений и нехватке кэша. Проверяйте аварийное переключение в первый же день, а не во время первого инцидента. Расширяйте возможности сегментирования, локальности данных на основе зон и развертываний в нескольких регионах по мере роста объема данных и требований к доступности. Инфраструктура занимается механикой; ваша ответственность — понять архитектуру достаточно глубоко, чтобы найти правильные компромиссы для вашей рабочей нагрузки, и неустанно проверять эти предположения.