Администрирование базы данных MongoDB для веб-приложения

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Администрирование базы данных MongoDB для веб-приложения
Сложная
постоянная поддержка
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Администрирование базы данных MongoDB для веб-приложения

MongoDB — документная база с горизонтальным масштабированием. Flex-схема удобна при разработке, но в продакшне требует дисциплины: без индексов запросы превращаются в collection scan, без компактификации WiredTiger не освобождает место, без мониторинга oplog-а реплики отстают и теряют синхронизацию.

Начальный аудит

// mongosh
use mydb

// Статистика базы
db.stats({ scale: 1024 * 1024 }) // в МБ

// Статистика коллекций
db.runCommand({ listCollections: 1 }).cursor.firstBatch.forEach(c => {
    const stats = db[c.name].stats({ scale: 1024 })
    printjson({
        name: c.name,
        docs: stats.count,
        size_kb: stats.size,
        storageSize_kb: stats.storageSize,
        totalIndexSize_kb: stats.totalIndexSize,
        nindexes: stats.nindexes
    })
})

// Индексы коллекции с размерами
db.orders.stats().indexSizes

// Операции, выполняющиеся прямо сейчас (> 1 секунды)
db.currentOp({ "secs_running": { $gt: 1 } })

Индексирование

// Составной индекс для типичного запроса по пользователю и дате
db.orders.createIndex(
    { user_id: 1, created_at: -1 },
    { background: true, name: "idx_user_date" }
)

// Частичный индекс — только для активных заказов
db.orders.createIndex(
    { created_at: -1 },
    {
        partialFilterExpression: { status: { $in: ["pending", "processing"] } },
        name: "idx_active_orders_date"
    }
)

// TTL индекс для автоудаления устаревших сессий
db.sessions.createIndex(
    { expires_at: 1 },
    { expireAfterSeconds: 0, name: "ttl_sessions" }
)

// Проверка использования индексов
db.orders.aggregate([
    { $indexStats: {} }
]).forEach(stat => {
    if (stat.accesses.ops === 0) {
        print("UNUSED INDEX: " + stat.name)
    }
})

background: true позволяет создавать индексы без блокировки базы. В MongoDB 4.2+ это поведение по умолчанию.

Explain и оптимизация запросов

// Анализ плана выполнения запроса
db.orders.find({ user_id: "507f1f77bcf86cd799439011", status: "pending" })
    .explain("executionStats")

// Ключевые поля в executionStats:
// - stage: "COLLSCAN" означает полный скан коллекции — нужен индекс
// - stage: "IXSCAN" — использует индекс, хорошо
// - nReturned vs totalDocsExamined — чем ближе к 1:1, тем лучше индекс
// - executionTimeMillis — время выполнения

Включение профайлера для поиска медленных запросов:

// Профилировать запросы > 100ms
db.setProfilingLevel(1, { slowms: 100 })

// Просмотр медленных запросов
db.system.profile.find(
    { millis: { $gt: 100 } },
    { ns: 1, command: 1, millis: 1, ts: 1 }
).sort({ millis: -1 }).limit(20)

// Выключить профайлер (влияет на производительность!)
db.setProfilingLevel(0)

Replica Set: настройка и мониторинг

// Инициализация replica set
rs.initiate({
    _id: "rs0",
    members: [
        { _id: 0, host: "mongo1:27017", priority: 2 },
        { _id: 1, host: "mongo2:27017", priority: 1 },
        { _id: 2, host: "mongo3:27017", arbiterOnly: true }
    ]
})

// Статус репликации
rs.status()

// Лаг реплики (критично: если oplog переполнится — реплика потеряет синхронизацию)
rs.printSecondaryReplicationInfo()

// Размер oplog (должен покрывать несколько часов операций)
rs.printReplicationInfo()
// oplog size: 5760MB
// log length start to end: 14400 secs (4 hrs)
// Если меньше 4–6 часов — увеличить:
db.adminCommand({ replSetResizeOplog: 1, size: 10240 }) // 10 GB

Резервное копирование

mongodump — для баз до нескольких ГБ:

# Бэкап с точкой согласованности на replica set
mongodump \
  --uri="mongodb://backup_user:password@mongo1:27017,mongo2:27017/mydb?replicaSet=rs0" \
  --readPreference=secondary \
  --oplog \
  --gzip \
  --out=/backups/dump_$(date +%Y%m%d_%H%M)

# Восстановление
mongorestore \
  --uri="mongodb://admin:password@localhost:27017" \
  --gzip \
  --oplogReplay \
  /backups/dump_20250101_0300

mongodump блокирует чтение через --oplog только на secondary — для продакшн всегда снимать бэкап с secondary.

Для больших баз (>100 ГБ) — снапшоты файловой системы (LVM, AWS EBS Snapshot) быстрее физически.

WiredTiger: компактификация

MongoDB (WiredTiger) не возвращает освобождённое место ОС автоматически. После массового удаления документов — запустить compact:

// Компактификация конкретной коллекции
// ВНИМАНИЕ: блокирует базу на время выполнения!
db.runCommand({ compact: "orders" })

// На replica set — compact поочерёдно на secondary, потом переключить primary
// Запускать в окно обслуживания

Проверить overhead до и после:

const stats = db.orders.stats({ scale: 1024 * 1024 })
console.log({
    dataSize: stats.size.toFixed(1) + ' MB',
    storageSize: stats.storageSize.toFixed(1) + ' MB',
    overhead_pct: ((1 - stats.size / stats.storageSize) * 100).toFixed(1) + '%'
})

Управление пользователями

use mydb

// Создание пользователя приложения
db.createUser({
    user: "app_user",
    pwd:  "strong_password",
    roles: [
        { role: "readWrite", db: "mydb" }
    ]
})

// Только чтение для аналитики
db.createUser({
    user: "analytics",
    pwd:  "analytics_password",
    roles: [
        { role: "read", db: "mydb" }
    ]
})

// Список пользователей
db.getUsers({ showCredentials: false })

Connection pooling

Mongoose (Node.js) по умолчанию открывает 5 соединений. Для высоконагруженных приложений:

mongoose.connect(process.env.MONGO_URI, {
    maxPoolSize:     50,  // максимум соединений в пуле
    minPoolSize:     5,
    serverSelectionTimeoutMS: 5000,
    socketTimeoutMS: 45000,
    connectTimeoutMS: 10000
})

Для PHP (MongoDB extension):

$client = new MongoDB\Client(
    "mongodb://app_user:password@mongo1:27017,mongo2:27017/mydb",
    ["replicaSet" => "rs0", "readPreference" => "secondaryPreferred"],
    ["typeMap" => ["root" => "array", "document" => "array"]]
);

Мониторинг через mongostat и mongotop

# Статистика операций в реальном времени (каждую секунду)
mongostat --uri="mongodb://admin:password@localhost:27017" --discover

# Топ коллекций по времени чтения/записи
mongotop --uri="mongodb://admin:password@localhost:27017" 5

# Ключевые метрики для мониторинга в Prometheus (через mongodb_exporter):
# - mongodb_ss_globalLock_currentQueue_total > 0 — очередь блокировок
# - mongodb_ss_connections_current vs maxIncomingConnections
# - replication lag на secondary
# - opcounters: insert/query/update/delete per second