Что такое OOM (Out Of Memory) в Linux?

Ответ

OOM (Out Of Memory) — это состояние, когда ядро Linux не может удовлетворить запрос на выделение памяти, и все доступная оперативная память (RAM) и swap исчерпаны.

Что происходит при OOM? Ядро активирует OOM Killer, который по своему алгоритму выбирает и принудительно завершает один или несколько процессов (SIGKILL), чтобы освободить память и стабилизировать систему.

Практическая работа с OOM:

  • Проверить настройки overcommit:
    sysctl vm.overcommit_memory
    cat /proc/sys/vm/overcommit_memory
  • Посмотреть текущие оценки процессов: Можно увидеть, какие процессы являются первыми кандидатами на завершение.
    # Вывести список процессов с их oom_score (чем выше, тем вероятнее завершение)
    for proc in /proc/[0-9]*/; do pid=$(basename $proc); if [ -f "$proc/oom_score" ]; then printf "PID: %5s Score: %5s Adj: %5s Cmd: " $pid $(cat $proc/oom_score) $(cat $proc/oom_score_adj 2>/dev/null); cat $proc/cmdline; echo; fi; done | sort -k3 -rn | head -20

Основные причины OOM в DevOps-практике:

  1. Утечки памяти в приложениях.
  2. Некорректные или отсутствующие лимиты памяти для контейнеров. Например, контейнер без -m в Docker может занять всю память хоста.
  3. Недостаточный мониторинг. Система достигает предела до того, как сработают алерты.
  4. Неправильная настройка vm.overcommit_memory. Значение 1 (always overcommit) может отложить, но усугубить проблему.

Профилактика: Помимо настройки oom_score_adj для критичных сервисов, ключевая задача — внедрение лимитов (cgroups) и активного мониторинга с помощью таких инструментов, как node_exporter для Prometheus.

Ответ 18+ 🔞

А, ну вот, опять про эту память, блядь. Слушай, сейчас объясню на пальцах, что за пиздец такой — OOM. Это когда твой сервак, как последний алкаш, выпил всю оперативку до дна, и своп ему уже не помогает, ёпта. Система просто встаёт в ступор и думает: "Ну всё, пиздец, ядрёна вошь, терпения ноль ебать".

И тут в дело вступает наш спаситель-палач — OOM Killer. Этот хитрая жопа в ядре Linux начинает судорожно искать, кого бы прирезать, чтобы всем остальным жилось лучше. Берёт, выбирает самый жирный и бесполезный (по его мнению) процесс и — хуй с горы! — шлёт ему SIGKILL. Надеюсь, это не был твой продовый воркер, а то будет вам хиросима и нигерсраки.

Ну-ка, руки прочь от клавиатуры, давай посмотрим, что у нас творится:

  • Глянем, не обманывает ли нас система насчёт памяти: (overcommit — это когда она обещает больше, чем есть, а потом охуевает)
    sysctl vm.overcommit_memory
    cat /proc/sys/vm/overcommit_memory
  • А теперь самое интересное — кто следующий на вылет? Запусти эту команду и увидишь список кандидатов на расстрел. Чем цифра в Score больше — тем ближе чувак к тому, чтобы накрыться медным тазом.
    for proc in /proc/[0-9]*/; do pid=$(basename $proc); if [ -f "$proc/oom_score" ]; then printf "PID: %5s Score: %5s Adj: %5s Cmd: " $pid $(cat $proc/oom_score) $(cat $proc/oom_score_adj 2>/dev/null); cat $proc/cmdline; echo; fi; done | sort -k3 -rn | head -20

А теперь, чувак, давай разберём, из-за чего обычно вся эта ебанина случается в наших, DevOps'ских, краях:

  1. Приложение — распиздяй. Написано криво, память жрёт, а отдавать не хочет. Классика, блядь.
  2. Контейнеры без лимитов — это пиздец. Запустил докер без -m и думаешь: "Да похуй, авось пронесёт". Не пронесёт, сука. Один контейнер сожрёт всё, а остальные будут лежать и плакать.
  3. Мониторинг проёбан. Графики в прометеусе красивые, а алерт пришёл уже тогда, когда все пользователи тебе в душу бога мать посылают. Удивление пиздец!
  4. Настройка vm.overcommit_memory в режиме "авось". Поставил 1 (всегда обещай), система всем радостно кивала, а потом — бац! — и реальной памяти нет. Вот тут-то OOM Killer и начинает свою кровавую жатву.

Что делать, чтобы не охуеть от неожиданности? Ну, кроме как настраивать oom_score_adj для важных процессов (чтобы их убивали в последнюю очередь), надо ставить лимиты через cgroups и мониторить так, чтобы видеть проблему за километр. Выручает node_exporter для Prometheus — смотри на графики использования памяти и swap, ставь алерты пораньше, пока не стало поздно. А то потом будешь сам от себя охуевать, разгребая последствия.