Вопрос: MongoDB убил OOM


мы выполняем репликацию mongodb на трех машинах. Все три машины имеют около 16 ГБ, но только 255 Мбайт Swap. Swappiness остается по умолчанию 60. Машины работают CentOS 6.4. Базы данных намного больше, чем 16 ГБ, но это нормально для нас. Действительно рабочий набор намного меньше.

Проблема, с которой мы сталкиваемся, заключается в том, что основное потребление поглощает всю доступную память, а не получает OOM-Killed. Я знаю, что так управляет памятью монгодб.

После того, как сервер получает OOM, кто-то должен вручную перезапустить его.

Есть ли способ предотвратить убийство монгодба от уничтожения ООМ? Настроить swappiness? Увеличить пространство подкачки? Я думаю, что эти настройки только увеличат льготный период до того, как монгод будет убит.


5
2017-09-07 17:37


Источник


Вы используете 2.4.0 - 2.4.2? - Chris Winslett
Мы работаем с 2.2.3. - bjoernhaeuser
Дубликат stackoverflow.com/q/6861184/86060 - tylerl
Извините, я не хочу ограничивать использование памяти, я просто хочу предотвратить OOM :) - bjoernhaeuser


Ответы:


Убийца OOM - это не способ кто угодно управляет памятью; это ядерные ядра Linux, чтобы справиться с фатальным сбоем в последней надежде избежать блокировки системы!

Что вам нужно сделать:

  • убедитесь, что у вас есть своп. Если вы уверены, добавьте еще больше.

  • использовать ограничения ресурсов! В LEAST для приложений вы ожидаете, что будет использовать память (и даже более того, если вы не ожидаете их - те, которые обычно оказываются проблематичными). См. Команды ulimit -v (или limit addressspace) в своей оболочке и поместите их перед запуском приложения в его сценарии инициализации. Вы также должны ограничить другие вещи (например, количество процессов -u и т. Д.) ... Таким образом, приложение получит ошибку ENOMEM, когда памяти недостаточно, вместо того, чтобы ядро ​​давало им несуществующую память, а потом идя, берсерк убивал все вокруг !

  • скажите ядру не перекомпилировать память. Вы можете сделать:

    echo "0"> / proc / sys / vm / overcommit_memory

    или даже лучше (в зависимости от вашего объема пространства подкачки)

    echo "2"> / proc / sys / vm / overcommit_memory; echo "80"> / proc / sys / vm / overcommit_ratio

    Видеть Выключение overcommit для получения дополнительной информации об этом.

    Это даст указание ядру быть более осторожным при предоставлении памяти приложений, на которой это действительно не так (сходство с глобальным экономическим кризисом в мире поражает)

  • как последний курорт, если все, что находится в вашей системе, кроме MangoDB, является расходным (но сначала исправьте два пункта выше!), вы можете уменьшить шансы на его убийство (или даже убеждаться, что он не будет убит, даже если альтернатива - это зависающая машина, ничего не работающая) путем настройки / proc / $ pid / oom_score_adj и / или / proc / $ pid / oom_score.

    echo "-1000"> / proc / `pidof mangod` / oom_score_adj

    Видеть Укрощение убийцы OOM для получения дополнительной информации по этому вопросу.


6
2017-09-08 00:16



Спасибо за это подробное объяснение темы. Я могу просто принять одну рекомендацию: увеличьте пространство подкачки. Верный? Ваше объяснение охватывает эту тему по очень широкому подходу, но я думаю, что моя проблема очень специфична для mongodb. - bjoernhaeuser
Нет, не совсем. Вы видите, что OOM не запускается, когда приложение запрашивает память, и нет никого (в таком случае что-то поменялось бы или приложение получило бы ошибку -ENOMEM), но когда ядро ​​требуется память (например, для выделения памяти для TCP / IP), и их нет. И хотя вы часто можете избежать этого, увеличивая объем пространства подкачки и vm.swappiness, лучше убедиться, что ядро ​​не превзойдено, поэтому у него будет достаточно памяти. И ограничение mongodb (и других процессов) позволит им получить ENOMEM (и обрабатывать его чисто) вместо ядра OOMing. - Matija Nalis
MongoDB не управляет памятью, это всего лишь файлы mmap. Overcommit уже отключен. - bjoernhaeuser
Я знаю, что MongoDB делает mmap (2) вместо brk (2) для баз данных, но mmap также нуждается в памяти для размещения на странице данных. Если свободная память недоступна при доступе к новой области mmaped-данных, ядру нужно будет вывести (или заменить, но не в MongoD dbs) некоторые данные. Обратите внимание, что это не относится к OOM самостоятельно (если не требуется своп-выход, и все свопы используются). OOM будет вызван, если используется вся память, а ядро ​​нуждается и не может получить некоторые из них без подкачки / замены на диск. Я предполагаю, что вы не запускаете mongod в качестве процесса init, поэтому ваши другие процессы могут быть триггерами: следовательно, советы - Matija Nalis
Запуск Puppet запускает OOM - bjoernhaeuser