MongoDB завершает работу, когда ему не хватает памяти

11

У меня есть следующая конфигурация:

  • хост-машина, которая запускает три док-контейнера:
    • MongoDB
    • Redis
    • Программа, использующая предыдущие два контейнера для хранения данных

Redis и MongoDB используются для хранения огромных объемов данных. Я знаю, что Redis должен хранить все свои данные в оперативной памяти, и я в порядке с этим. К сожалению, происходит то, что Монго начинает занимать много ОЗУ, и как только ОЗУ хоста заполнится (здесь мы говорим о 32 ГБ), происходит сбой либо Монго, либо Redis.

Я прочитал следующие предыдущие вопросы об этом:

  1. Ограничение использования оперативной памяти MongoDB : по-видимому, большая часть оперативной памяти используется кэшем WiredTiger
  2. MongoDB ограничить память : здесь, видимо, проблема заключалась в данных журнала
  3. Ограничьте использование памяти RAM в MongoDB : здесь они предлагают ограничить память mongo, чтобы она использовала меньший объем памяти для своего кэша / logs / data
  4. MongoDB использует слишком много памяти : здесь говорят, что это система кэширования WiredTiger, которая стремится использовать как можно больше оперативной памяти для обеспечения более быстрого доступа. Они также заявляютit's completely okay to limit the WiredTiger cache size, since it handles I/O operations pretty efficiently
  5. Есть ли возможность ограничить использование памяти mongodb? : опять кешируя, они тоже добавляютMongoDB uses the LRU (Least Recently Used) cache algorithm to determine which "pages" to release, you will find some more information in these two questions
  6. MongoDB индекс / RAM отношение : цитата:MongoDB keeps what it can of the indexes in RAM. They'll be swaped out on an LRU basis. You'll often see documentation that suggests you should keep your "working set" in memory: if the portions of index you're actually accessing fit in memory, you'll be fine.
  7. как освободить кеширование, которое использует MongoDB? : тот же ответ, что и в 5.

Теперь, по-видимому, из всех этих ответов я понимаю, что:

  1. Для более быстрого доступа для монго было бы лучше разместить все индексы в оперативной памяти. Однако, в моем случае, я в порядке с индексами, частично находящимися на диске, поскольку у меня довольно быстрый SSD.
  2. RAM в основном используется для кеширования монго.

Учитывая это, я ожидал, что Монго попытается использовать как можно больше места в ОЗУ, но при этом сможет функционировать также с небольшим объемом ОЗУ и извлекать большинство данных с диска. Тем не менее, я ограничил объем памяти Docker-контейнера mongo (например, до 8 ГБ), используя --memoryи --memory-swap, но вместо того, чтобы извлекать данные с диска, mongo просто зависал, как только ему не хватало памяти.

Как заставить монго использовать только доступную память и извлекать с диска все, что не помещается в память?

Симона Бронзини
источник
Это называется OOM killer. MongoDB предназначен для работы на аппаратном оборудовании. Я бы никогда не использовал его на искусственно ограниченных ресурсах. Если у вас небольшая база данных, MongoDB - не идеальный выбор. Если у вас большая база данных (от трех до миллиона записей), ограничение ресурсов - плохой выбор. По твоей проблеме: нельзя есть торт и есть его. Выбирать.
Маркус У
При правильной настройке MongoDB не должен аварийно завершать работу при нехватке памяти. Можете ли вы подтвердить конкретную версию сервера MongoDB и O / S, которые вы используете, а также более подробно описать сбой? Например, есть ли в журнале MongoDB какие-либо сообщения или они dmesgсвязаны с неожиданным завершением работы? Наиболее вероятная возможность использования Docker заключается в том, что процессы в контейнере обнаруживают общую доступную оперативную память, а не ограничение контейнера.
Стенни
В соответствии с Замечаниями по производству MongoDB : если вы работаете mongodв контейнере ( lxc, cgroupsDocker и т. Д.), Который не имеет доступа ко всей оперативной памяти, доступной в системе, вы должны установить storage.wiredTiger.engineConfig.cacheSizeGBзначение, меньшее объема оперативной памяти, доступной в контейнер. Точное количество зависит от других процессов, запущенных в контейнере, но обычно не должно превышать значение по умолчанию 50% ОЗУ минус 1 ГБ.
Стенни

Ответы:

9

В соответствии с MongoDB БОЛ Здесь Изменено в версии 3.4: Значения могут варьироваться от 256MBдо 10TBи может быть float. Кроме того, значение по умолчанию также изменилось.

Начиная 3.4с внутреннего кеша WiredTiger по умолчанию будет использовать большее из следующих значений:

50% of RAM minus 1 GB, or
256 MB.

С WiredTigerMongoDB используется как WiredTiger, так internal cache и filesystem cache.

Через filesystem cache, MongoDB автоматически использует всю свободную память, которая не используется WiredTiger cacheни другими процессами.

Storage.wiredTiger.engineConfig.cacheSizeGB ограничивает размер WiredTigerвнутреннего кэша. Операционная система будет использовать доступную свободную память для кэша файловой системы, что позволяет сжатым файлам данных MongoDB оставаться в памяти. Кроме того, он operating systemбудет использовать любую свободную оперативную память для буферизации блоков файловой системы и кэша файловой системы.

Для размещения дополнительных потребителей оперативной памяти может потребоваться уменьшить WiredTigerразмер внутреннего кэша.

Для дальнейшего использования вашего WiredTiger Storage Engine и параметров файла конфигурации

Г-н Хайдар Али Хан
источник
4

На самом деле, если вы присмотритесь, не "mongod" умирает за "нехватку памяти", а менеджер OOM (нехватки памяти) ядра убивает mongod, потому что он имеет наибольшее использование памяти.

Да, вы можете попытаться решить проблему с параметром конфигурации monngodb cacheSizeGB , но в среде контейнеров лучше использовать cgroups для ограничения ресурсов, которые получает любой из ваших трех контейнеров.

JJussi
источник