Тюнинг MongoDB: WiredTiger, индексы, запросы

Представьте: сервер с 32 ГБ RAM, MongoDB использует 16 ГБ под кэш WiredTiger, но запросы всё равно выполняются за секунды. Причина — неэффективные индексы и неправильная конфигурация. Мы сталкивались с таким не раз: COLLSCAN вместо IXSCAN, кэш вытесняется страницами с диска, а агрегации съедают всю

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Тюнинг MongoDB: WiredTiger, индексы, запросы
Сложный
~2-3 дня

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

Часто задаваемые вопросы

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

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

Представьте: сервер с 32 ГБ RAM, MongoDB использует 16 ГБ под кэш WiredTiger, но запросы всё равно выполняются за секунды. Причина — неэффективные индексы и неправильная конфигурация. Мы сталкивались с таким не раз: COLLSCAN вместо IXSCAN, кэш вытесняется страницами с диска, а агрегации съедают всю память. Оптимизация MongoDB — комплексная задача, включающая настройку движка WiredTiger, проектирование индексов и профилирование медленных запросов. Без системного подхода даже мощные серверы работают неэффективно. Наши инженеры имеют сертификаты MongoDB и 10+ лет опыта в этой области. В этой статье делимся практическими приёмами, которые помогли нашим клиентам сократить время ответа до 50%. Рассмотрим типичные ошибки и способы их устранения. Особое внимание уделим правилу ESR для индексов и настройке кэша WiredTiger — эти два момента дают наибольший эффект.

Проблемы, которые решаем

Неэффективная настройка кэша WiredTiger

По умолчанию MongoDB выделяет 50% RAM под кэш. На сервере с 32 ГБ это 16 ГБ. Но без явной установки cacheSizeGB кэш может быть вытеснен другими процессами. Мы всегда задаём его вручную, оставляя запас для ОС и дискового кэша.

# /etc/mongod.conf storage: wiredTiger: engineConfig: cacheSizeGB: 12 # Для сервера 32 GB journalCompressor: snappy collectionConfig: blockCompressor: snappy indexConfig: prefixCompression: true 

Мониторинг: db.serverStatus().wiredTiger.cache. Если pages evicted by application threads > 0, кэш под давлением — увеличьте cacheSizeGB.

Индексы: отсутствие или неправильный порядок

Без индекса любой запрос превращается в COLLSCAN. Главное правило — ESR (Equality, Sort, Range). Вот как строить составной индекс:

// Запрос: найти активные заказы пользователя, отсортировать по дате db.orders.find({ user_id: ObjectId("..."), status: "active" }).sort({ created_at: -1 }) // Правильный индекс: equality → sort db.orders.createIndex({ user_id: 1, status: 1, created_at: -1 }) 

Медленные агрегации с $lookup

Самая частая ошибка — $match после $lookup. Оптимальный порядок:

db.orders.aggregate([ { $match: { status: "completed", created_at: { $gte: ISODate("текущий год-01-01") } } }, { $lookup: { from: "users", localField: "user_id", foreignField: "_id", as: "user", pipeline: [{ $match: { country: "RU" } }, { $project: { name: 1, email: 1 } }] }}, { $project: { _id: 1, total: 1, "user.name": 1 } } ]) 

Для параллельных пайплайнов используйте $facet.

Настройка кэша WiredTiger: ключевые параметры

Ключевой параметр — cacheSizeGB. Установите его в 60–70% от доступной RAM, но не более 20 ГБ на современных версиях (согласно официальной документации MongoDB). Оставшуюся память отдайте ОС и дисковому кэшу. Для сервера 64 ГБ оптимально cacheSizeGB: 40, но с учётом других процессов — обычно 35–40.

Индексы: проектирование и уход

Используйте правило ESR для составных индексов. Регулярно проверяйте неиспользуемые индексы: db.aggregate([{ $indexStats: {} }]). Индексы с accesses.ops == 0 — мёртвый груз, их стоит удалять. Это экономит до 20% ОЗУ.

Когда стоит шардировать MongoDB?

Шардинг оправдан, если данные превышают 200 ГБ или нагрузка на запись более 10 000 RPS на один сервер. Ключ шардирования выбирайте с высокой кардинальностью, например хеш от user_id.

Как мы это делаем: кейс

Оптимизировали MongoDB для интернет-магазина — одного из наших клиентов — с каталогом в 5 млн товаров. Время запросов по категориям и цене — 2-3 секунды. Решение:

  • Составные индексы по (category, price, created_at).
  • cacheSizeGB = 20 на сервере 64 ГБ.
  • Аналитические запросы на secondary (readPreference: secondaryPreferred).
  • Заменили $lookup с пост-фильтрацией на pipeline.

Результат: время ответа упало до 50 мс, нагрузка на CPU снизилась на 30%. Наша команда гарантирует, что такой подход к индексации сокращает время ответа в 2 раза по сравнению с типовой конфигурацией. Средняя экономия клиентов за первый год — 200 000–500 000 руб на содержании серверов. Для срочных задач доступна экспресс-диагностика за 1 день — свяжитесь с нами.

Регулярная проверка неиспользуемых индексов

Индексы с accesses.ops == 0 занимают память и замедляют запись. Раз в месяц запускайте $indexStats и удаляйте неиспользуемые. Это экономит до 20% оперативной памяти на индексах. Правильный cacheSizeGB даёт прирост скорости на 40% против стандартных настроек.

Процесс работы и стоимость

  1. Аудит: профайлер, explain, анализ индексов.
  2. Проектирование: расчет cacheSizeGB, индексы по ESR.
  3. Реализация: настройка конфигурации, создание/удаление индексов, оптимизация запросов.
  4. Тестирование: нагрузочное тестирование, сравнение метрик.
  5. Деплой: применение изменений, мониторинг.

Сроки оптимизации — от 3 до 10 рабочих дней. Стоимость рассчитывается индивидуально после бесплатного аудита. Экономия на серверной инфраструктуре может достигать 30% за счёт снижения нагрузки. Наша оптимизация окупается за 2-3 месяца.

Что входит в оптимизацию MongoDB

  • Полный аудит текущей конфигурации и производительности.
  • Проектирование схемы индексов с учётом бизнес-логики.
  • Настройка WiredTiger (cacheSizeGB, компрессия, журнал).
  • Оптимизация медленных запросов и агрегаций.
  • Документация изменений и рекомендации по эксплуатации.
  • Обучение команды и передача доступов.
  • Поддержка в течение 30 дней после внедрения.

Чеклист тюнинга

Компонент Действие Критерий
WiredTiger cache Установить явно cacheSizeGB = 60-70% от RAM
Индексы Проверить все регулярные запросы Ни одного COLLSCAN
Неиспользуемые индексы Удалить accesses.ops == 0
Aggregation $match первым Нет $lookup без фильтра
Read preference Аналитика на secondary readPreference: secondaryPreferred

Сравнение распространённых подходов к индексации

Подход Преимущество Недостаток
Составные индексы по ESR Оптимальны для сортировки и фильтрации Требуют точного порядка полей
Покрывающие индексы Запрос не обращается к документу Увеличивают размер индекса
Хеш-индексы Идеальны для шардинга Только точное равенство

Пример включения профайлера

db.setProfilingLevel(1, { slowms: 50 }); db.getProfilingStatus(); db.system.profile.aggregate([ { $group: { _id: "$ns", avgMillis: { $avg: "$millis" }, count: { $sum: 1 } } }, { $sort: { avgMillis: -1 } }, { $limit: 10 } ]) 
Совет по диагностике Если не знаете, с чего начать, включите профайлер на 50 мс и через час посмотрите top-10 медленных запросов. Часто проблема решается одним индексом.

Закажите аудит производительности MongoDB — получите консультацию инженера и план оптимизации.