Проблема: каталог с произвольными атрибутами «ломает» реляционную модель
Мы настраивали MongoDB для интернет-магазина электроники: каждая категория имеет уникальный набор характеристик (диагональ, количество ядер, объём памяти). В PostgreSQL пришлось бы городить EAV или JSON-поля — сложные запросы и падение производительности при 500 товарах. MongoDB решила это без боли: схема не фиксирована, а BSON-документы идеально ложатся на структуру товара. Наш клиент — магазин с 5000 товаров в 20 категориях — получил время ответа запросов под 10 мс без специальной оптимизации. Расскажем, как настроить такую базу под ключ.
Проблемы, которые решаем
- N+1 запросов при работе с документами — типичная ошибка, когда вместо вложенных массивов достают связанные документы отдельными запросами. Решение: использовать
$lookupв агрегации или хранить вложенные подмассивы. - Медленная запись без репликации — при падении единственного узла теряются данные за минуты. Replica Set из трёх серверов даёт RPO=0 и автоматическое переключение.
- Индексы не покрывают запросы — без частичных и составных индексов агрегации по статусу и дате выполняются за секунды вместо миллисекунд. С правильно настроенными индексами производительность запросов возрастает в 10–100 раз.
Как мы настраиваем MongoDB: кейс с Replica Set
Для того же интернет-магазина мы развернули кластер на трёх серверах (MongoDB 7.0, Ubuntu 22.04). Настроили Replica Set с двумя обычными узлами и одним скрытым для бэкапов. Connection string приложения: mongodb://myapp:password@mongo1:27017,mongo2:27017/myapp?replicaSet=rs0&readPreference=secondaryPreferred. В результате — отказоустойчивость и балансировка чтения на вторичные узлы. Нагрузка 10 000 запросов в секунду держится без задержек.
Установка и конфигурация
# Установка MongoDB 7.0 curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" > /etc/apt/sources.list.d/mongodb-org-7.0.list apt update && apt install -y mongodb-org systemctl enable mongod && systemctl start mongod # /etc/mongod.conf (основные настройки) net: port: 27017 bindIp: 127.0.0.1 # для продакшена замените на внутренний IP security: authorization: enabled storage: dbPath: /var/lib/mongodb wiredTiger: engineConfig: cacheSizeGB: 2 # 50% RAM replication: replSetName: "rs0" operationProfiling: slowOpThresholdMs: 100 mode: slowOp Индексы под типовые запросы
// Создаём индексы сразу при проектировании схемы // Уникальный индекс по email db.users.createIndex({ email: 1 }, { unique: true, background: true }) // Составной для сортировки заказов пользователя db.orders.createIndex({ userId: 1, createdAt: -1 }) // Частичный — только активные сессии db.sessions.createIndex( { userId: 1, expiresAt: 1 }, { partialFilterExpression: { revokedAt: { $exists: false } } } ) // TTL-индекс — автоудаление логов через 30 дней db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 }) // Текстовый поиск с русским языком db.articles.createIndex({ title: "text", body: "text" }, { default_language: "russian" }) // Wildcard для каталога с произвольными атрибутами db.products.createIndex({ "attributes.$**": 1 }) Агрегация: выручка по категориям
db.orders.aggregate([ { $match: { createdAt: { $gte: ISODate("2024-01-01"), $lt: ISODate("2024-04-01") }, status: "paid" } }, { $unwind: "$items" }, { $lookup: { from: "products", localField: "items.productId", foreignField: "_id", as: "product" } }, { $unwind: "$product" }, { $group: { _id: "$product.category", revenue: { $sum: { $multiply: ["$items.price", "$items.quantity"] } }, orders: { $addToSet: "$_id" } } }, { $project: { category: "$_id", revenue: { $round: ["$revenue", 2] }, orderCount: { $size: "$orders" } } }, { $sort: { revenue: -1 } } ]) Как выбрать топологию MongoDB для вашего проекта?
| Топология | Нагрузка | Объём данных | Отказоустойчивость | Сложность администрирования |
|---|---|---|---|---|
| Одиночный узел | до 10 000 оп/с | до 100 ГБ | Нет | Низкая |
| Replica Set | до 50 000 оп/с | до 10 ТБ | Автоматическое переключение | Средняя |
| Шардированный кластер | >50 000 оп/с | >10 ТБ | Высокая (горизонтальное масштабирование) | Высокая |
Почему Replica Set обязателен для продакшена?
Replica Set — минимальная конфигурация для production. Одиночный узел не обеспечивает отказоустойчивость: при сбое в работе сервера данные недоступны до восстановления. Replica Set из трёх узлов гарантирует автоматическое переключение на вторичный узел в течение секунд. RPO (точка восстановления) стремится к нулю. Для большинства приложений это оптимальный баланс надёжности и стоимости. Свяжитесь с нами — мы проведём аудит вашей текущей схемы и предложим оптимальную топологию.
Процесс работы
| Этап | Что делаем | Срок |
|---|---|---|
| Аналитика | Изучаем нагрузку, схемы, типовые запросы. Определяем необходимость шардинга. | 1 день |
| Проектирование | Выбираем топологию (Replica Set, шардинг), конфигурацию серверов, индексы. | 1 день |
| Реализация | Разворачиваем серверы, настраиваем репликацию, создаём индексы, пишем миграции. | 1–3 дня |
| Тестирование | Нагрузочное тестирование, проверка failover, мониторинг. | 1 день |
| Деплой | Переключение на продакшен, документация, обучение команды. | 1 день |
Что входит в работу
- Конфигурация сервера и сети (авторизация, TLS)
- Настройка Replica Set или шардированного кластера
- Создание индексов под нагрузку (частичные, TTL, текстовые)
- Оптимизация агрегационных запросов
- Интеграция с Mongoose/Node.js (схемы, хуки, виртуальные поля)
- Настройка мониторинга (MongoDB Atlas, Prometheus + Grafana)
- Резервное копирование (mongodump + автоматизация)
- Документация и инструкции для команды
Типичные ошибки при настройке MongoDB
- Отсутствие индексов для сортировки —
sort()без индекса приводит к сканированию коллекции (коллапс производительности). - Игнорирование размера WiredTiger cache — по умолчанию 50% RAM, для больших рабочих наборов нужно увеличивать до 70%.
- Глобальный
uniqueиндекс на email — блокирует регистрацию одинаковых email в разных статусах. Используйте частичные индексы. - Запись в Replica Set без
writeConcern: majority— при откате первичного узла данные могут быть потеряны.
Сроки и стоимость
Базовая настройка Replica Set с индексами и мониторингом — от 2 до 5 дней. Стоимость рассчитывается индивидуально и зависит от сложности схемы и количества узлов. Свяжитесь с нами для оценки вашего проекта — мы подготовим коммерческое предложение за один рабочий день. Закажите настройку MongoDB у сертифицированных специалистов с 10-летним опытом.
Почему стоит заказать настройку у нас?
Мы сертифицированные специалисты MongoDB (более 10 лет опыта в администрировании NoSQL). За это время настроили более 50 кластеров для проектов с нагрузкой до 100 000 запросов в секунду. Предоставляем гарантию на все работы — от 3 до 12 месяцев в зависимости от SLA. Получите консультацию прямо сейчас — мы бесплатно оценим вашу текущую архитектуру.







