Мы используем MongoDB уже несколько недель, общая тенденция, которую мы видели, заключается в том, что mongodb использует слишком много памяти (намного больше, чем весь размер его набора данных + индексы).
Я уже прочитал этот вопрос и этот вопрос , но, похоже, никто не решает проблему, с которой я столкнулся, они фактически объясняют то, что уже объяснено в документации.
Ниже приведены результаты команд htop и show dbs .
Я знаю, что mongodb использует IO с отображением в памяти, поэтому в основном ОС обрабатывает кэширование в памяти, и mongodb должен теоретически освобождать свою кэшированную память, когда другой процесс запрашивает свободную память , но, как мы видели, это не так.
OOM начинает работу, убивая другие важные процессы, такие как postgres, redis и т. Д. (Как можно видеть, чтобы преодолеть эту проблему, мы увеличили объем ОЗУ до 183 ГБ, который сейчас работает, но довольно дорогой. Монго использует ~ 87 ГБ ОЗУ, почти в 4 раза больше, чем весь его набор данных)
Так,
- Действительно ли такое потребление памяти ожидается и нормально? (Согласно документации, WiredTiger использует максимум ~ 60% оперативной памяти для своего кэша, но, учитывая размер набора данных, достаточно ли данных для того, чтобы можно было использовать 86 ГБ оперативной памяти?)
- Даже если ожидается использование памяти, почему mongo не отпустит выделенную память, если другой процесс начнет запрашивать больше памяти? Различные другие запущенные процессы были постоянно убиты linux oom, включая сам mongodb, прежде чем мы увеличили объем оперативной памяти, и это сделало систему совершенно нестабильной.
Благодарность !
источник
Ответы:
Итак, после следования подсказкам, данным loicmathieu и jstell, и немного покопав их, вот что я узнал о MongoDB, используя механизм хранения WiredTiger. Я ставлю это здесь, если кто-то сталкивался с такими же вопросами.
Потоки памяти, о которых я упоминал, все принадлежали 2012-2014 годам , все предшествующие WiredTiger и описывают поведение исходного механизма хранения MMAPV1, который не имеет отдельного кэша или поддержки сжатия.
Настройки кэша WiredTiger контролируют только объем памяти, непосредственно используемый механизмом хранения WiredTiger (но не общий объем памяти, используемый mongod). Многие другие вещи могут занимать память в конфигурации MongoDB / WiredTiger, например:
WiredTiger сжимает дисковое хранилище, но данные в памяти не сжимаются.
WiredTiger по умолчанию не синхронизирует данные при каждом коммите , поэтому файлы журнала также находятся в оперативной памяти, что сказывается на памяти. Также упоминается, что для эффективного использования операций ввода-вывода WiredTiger объединяет запросы ввода-вывода (ошибки кэширования), что также требует некоторой оперативной памяти (на самом деле грязные страницы (страницы, которые были изменены / обновлены) имеют список обновлений). на них хранятся в параллельном SkipList ).
WiredTiger хранит несколько версий записей в своем кэше (управление одновременной версией нескольких версий, операции чтения обращаются к последней подтвержденной версии перед их работой).
WiredTiger Сохраняет контрольные суммы данных в кеше.
Сам MongoDB использует память для обработки открытых соединений, агрегатов, серверного кода и т . Д.
Учитывая эти факты, полагаться на
show dbs;
это не было технически правильно, так как он показывает только сжатый размер наборов данных.Следующие команды могут использоваться для получения полного размера набора данных.
Эти результаты следующие:
Таким образом, кажется, что фактический размер набора данных + его индексы занимают около 68 ГБ этой памяти.
Учитывая все это, я предполагаю, что использование памяти теперь вполне ожидаемое, хорошая часть в том, что вполне нормально ограничить размер кэша WiredTiger, поскольку он довольно эффективно обрабатывает операции ввода-вывода (как описано выше).
Также остается проблема OOM, чтобы преодолеть эту проблему, так как у нас не было достаточно ресурсов, чтобы убрать mongodb, мы понизили oom_score_adj, чтобы OOM не убивал важные процессы на данный момент (то есть мы сказали OOM не убивать наши желаемые процессы ).
источник
oom_score_adj
решение лучшим, что вам удалось придумать?Я не думаю, что у вас есть проблема с MongoDB, так как jstell сказал, что MongoDB с WiredTiger будет использовать 50% доступной памяти, поэтому, если вы увеличите объем оперативной памяти вашего сервера, потребуется больше памяти.
Поэтому размер индексов DB + превышает размер, имейте в виду, что WiredTiger сжимает базу данных на диске, а также использует журналы моментальных снимков для записи изменений документа. Таким образом, реальный размер WiredTiger - это размер с использованием show dbs * compress_ration + size журналов снимков. Так что почти невозможно узнать точный ожидаемый размер.
Имейте также в виду , что такие инструменты , как
top
,ps
,htop
не проявляла память действительно , используемый приложением, refere к этому SOW вопрос для деталей: /programming/131303/how-to-measure-actual-memory -usage-оф-ан-приложения или-процессТеперь вернемся к вашей проблеме. У вас есть другие инструменты, работающие на том же хосте, и OOM убивает их. Я не знаком с Linux OOM, но вы уверены, что он убивает тех из-за MongoDB или ... просто из-за них (возможно, это убивает Postgres, потому что Postgres занимал слишком много памяти).
В любом случае, если у вас есть большая база данных Mongo, лучше не устанавливать ее на хосте, совместно используемом с другими базами данных, иначе у вас возникнет много трудностей, если возникнет проблема, подобная той, которую вы описали здесь, кто действительно вызывает проблему на хосте.
источник
Документы
Вы можете прочитать основные проблемы с памятью для MongoDB, а также это краткое обсуждение о проверке использования памяти .
Обзор использования памяти
Команда
db.serverStatus()
( docs ) может предоставить обзор использования памяти, а именно:Насколько велики ваши показатели?
db.stats()
может показать общий размер всех индексов, но мы также можем получить подробную информацию для одной коллекции, используяdb.myCollection.stats()
Например, эта команда будет сравнивать размеры индексов для каждой коллекции :
Теперь мы можем взглянуть на детали этой огромной коллекции, чтобы увидеть, какие из ее индексов являются самыми дорогостоящими:
Это может дать нам лучшее представление о том, где возможна экономия.
(В этом случае у нас
createTime
был довольно большой индекс - одна запись на документ - и мы решили, что можем жить без него.)источник
createTime
индекс был проблематичным, потому что он был уникальным для каждого отдельного документа, и эта коллекция была огромной. Индексирование других полей было в порядке, поскольку было меньше уникальных значений (значения были сгруппированы).