Команда увеличила внутренний cache WiredTiger после роста базы: чем больше данных останется рядом с движком, тем меньше чтений с накопителя — так выглядела логика решения. Первые графики подтвердили ожидание: в cache помещалось больше страниц, а выселение начиналось позже. Но на пике отчётов задержка p99 выросла, storage стал читать интенсивнее, а создание индекса оставляло узлу меньше запаса памяти. Причина не в том, что дополнительная RAM «не сработала».
Один и тот же физический объём одновременно нужен нескольким контурам. WiredTiger использует собственный cache как рабочую область движка, операционная система держит недавно прочитанные блоки файлов в filesystem cache, а процессы MongoDB, соединения, операции и обслуживание требуют память за пределами обоих кэшей. Увеличить один контур — значит сократить пространство для других, если RAM узла не выросла.
Один сервер обслуживает два разных кэша
Внутренний cache WiredTiger — это память, которой управляет сам движок хранения. В неё попадают страницы, необходимые для чтения и изменения данных, служебные структуры и результаты работы движка. WiredTiger знает состояние своих страниц и решает, какие из них можно выселить, какие изменены и требуют дополнительной обработки перед освобождением места. Filesystem cache, или файловый кэш ОС, устроен иначе. Операционная система использует доступную RAM для блоков файлов, которые недавно читались или записывались. Для файлов MongoDB это сокращает число физических обращений к накопителю: повторное чтение может получить данные из памяти ядра. Такой кэш не является «ничейной» свободной памятью и не входит во внутренний лимит WiredTiger.
Оба контура помогают одному запросу на разных участках пути. Нужный блок файла может сначала оказаться в файловом кэше, а затем быть преобразован в рабочую страницу WiredTiger. Но из этого нельзя заключать, что каждый байт базы постоянно хранится в двух полных копиях. Наборы страниц меняются, их размеры и представления различаются, а часть данных присутствует только в одном из контуров или вообще остаётся на storage.
На диске и внутри WiredTiger данные выглядят по-разному
Официальная документация MongoDB подчёркивает различие представлений. В filesystem cache блоки файлов остаются в том виде, в котором хранятся на накопителе, поэтому для них сохраняется эффект блочного сжатия. Во внутреннем cache данные коллекций находятся в рабочем, обычно распакованном представлении. Для индексов детали иные: их внутреннее представление может сохранять преимущество префиксного сжатия. Это различие важно для бюджета. Освободив гигабайт файлового кэша ради гигабайта внутреннего cache, команда не обязательно переносит туда одинаковый объём полезных данных. Сжатые блоки файлов и рабочие страницы движка нельзя сравнивать только по числу байтов. Реальный результат зависит от формы коллекций и индексов, степени сжатия, набора запросов и того, какие области повторно используются.
Когда внутренний cache увеличивают, показатель занятого места в нём может выглядеть лучше: полезные движку страницы остаются дольше. Одновременно ОС получает меньше пространства для сжатых файловых блоков. После смены активного набора или роста параллельности промахов файлового кэша становится больше, накопитель читает чаще, а очередь I/O удлиняет запросы. Улучшение одного снимка памяти тогда скрывает ухудшение всего пути данных.
Штатный размер — отправная точка, а не формула закупки
В MongoDB 8.0 штатный максимальный размер cache выбирается как большее из двух значений: половина памяти после вычета одного гигабайта либо 0,256 гигабайта. Это настройка по умолчанию, рассчитанная на типичный случай, когда на машине работает один процесс mongod. Она не доказывает, что одинаковая доля оптимальна для любого узла. Документация MongoDB советует без оснований не увеличивать cache выше значения по умолчанию. Это не запрет на изменение, а предупреждение о цене: память будет изъята у filesystem cache и других потребителей. Если расширение внутренней области не улучшает обязательную фазу или вызывает больше чтений с накопителя, формально больший cache ухудшает экономику узла.
В контейнере или виртуальной машине особенно опасно считать от всей RAM физического хоста. Для процесса важна память, действительно доступная внутри его границы. MongoDB отдельно предупреждает, что автоматический расчёт может требовать проверки при ограничениях контейнера. Большой запас на хосте не отменяет меньший лимит среды, а неверная база расчёта оставляет меньше места и движку, и ОС.
Eviction — нормальная работа, пока она не отнимает время запросов
Eviction означает выселение страниц из внутреннего cache для освобождения места. Это штатный механизм WiredTiger, а не самостоятельный признак аварии. Cache конечен, набор обращений меняется, поэтому некоторые страницы должны уступать место более нужным. Сам факт выселения не доказывает, что RAM мало или настройка неверна. Цена возникает, когда освобождение места перестаёт быть фоновой работой. При давлении на cache потоки приложений могут помогать eviction вместо того, чтобы сразу продолжать запрос. Если выселенная страница вскоре снова нужна, появляется повторное чтение и обработка. Одновременно увеличиваются I/O и задержка, а пропускная способность обязательной фазы падает.
Поэтому один снимок bytes currently in cache мало говорит о качестве сервиса. Высокая заполненность может быть нормальной: память и должна использоваться. Большое число выселений тоже может соответствовать устойчивой нагрузке. Бизнес-проблема начинается там, где изменения cache совпадают по времени с участием прикладных потоков в eviction, ростом чтений или записей и ухудшением p99 — задержки, быстрее которой заканчиваются 99 процентов запросов.
Dirty pages, checkpoint и journal решают разные задачи
Изменённые, или dirty, страницы нельзя выселять так же просто, как неизменённые. WiredTiger должен согласовать их состояние и записать необходимое представление данных. Это добавляет работу движку и storage, но eviction не становится от этого checkpoint. Выселение управляет местом в cache, а checkpoint фиксирует согласованную точку данных на накопителе. Journal выполняет ещё одну роль. Это журнал предварительной записи, который помогает восстановить изменения, произошедшие между checkpoint, если процесс или узел завершился аварийно. Нельзя считать journal и checkpoint двумя названиями одной записи, а рост journal I/O — доказательством неудачного eviction. Их потоки могут конкурировать за накопитель, но причины и гарантии у них разные.
Filesystem cache также не превращается в источник истины. Он ускоряет доступ к файловым блокам, однако постоянные данные остаются на storage в соответствии с правилами durability MongoDB. После холодного запуска узла или вытеснения блоков нужные области снова читаются с накопителя. Сохранившийся кэш способен временно помочь после перезапуска одного процесса, поэтому любой process restart нельзя автоматически называть полным обнулением файлового кэша.
Бюджет узла должен сохранять полезную работу
В исходном сценарии команде нужно сравнить не два размера cache, а два результата бизнеса. Если больший внутренний cache снижает повторную работу WiredTiger, но вытесняет сжатые файловые блоки и повышает p99, выигрыш сомнителен. Если меньший cache оставляет место ОС, но прикладные потоки регулярно заняты eviction, баланс сдвинут в другую сторону. Page-level NVMe capacity класса gigaRAM можно рассматривать только для действительно менее активных системных страниц. Активная рабочая память WiredTiger и горячие файловые страницы должны оставаться в DRAM: возврат через NVMe добавляет задержку и I/O. Такой уровень не понимает коллекции, индексы или dirty state, не управляет eviction и не заменяет настройку cache, постоянное хранилище, journal или checkpoint.
Публичная продуктовая страница не подтверждает совместимость с MongoDB, фиксированную экономию либо автоматическое управление её внутренним cache. Дополнительная ёмкость имеет смысл лишь там, где менее активная часть отделима без ущерба обязательной фазе. Итоговая цель — не занять максимум памяти в WiredTiger, а сохранить p99, throughput и устойчивость узла при приемлемой стоимости.
Источники. MongoDB 8.0: WiredTiger Storage Engine описывает внутренний и файловый cache, штатный размер, сжатие, checkpoint и journal.
Production Notes уточняет предпосылку одного mongod, другие расходы памяти и ограничения среды.
FAQ: Diagnostics и serverStatus используются для смысла eviction и участия прикладных потоков, без универсальных порогов.
MongoDB Journaling подтверждает роль журнала между checkpoint.
Meta TMO приведён только для общей механики страничного переноса, gigaRAM — только для позиционирования класса решения.