Ответ
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-практике:
- Утечки памяти в приложениях.
- Некорректные или отсутствующие лимиты памяти для контейнеров. Например, контейнер без
-mв Docker может занять всю память хоста. - Недостаточный мониторинг. Система достигает предела до того, как сработают алерты.
- Неправильная настройка
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'ских, краях:
- Приложение — распиздяй. Написано криво, память жрёт, а отдавать не хочет. Классика, блядь.
- Контейнеры без лимитов — это пиздец. Запустил докер без
-mи думаешь: "Да похуй, авось пронесёт". Не пронесёт, сука. Один контейнер сожрёт всё, а остальные будут лежать и плакать. - Мониторинг проёбан. Графики в прометеусе красивые, а алерт пришёл уже тогда, когда все пользователи тебе в душу бога мать посылают. Удивление пиздец!
- Настройка
vm.overcommit_memoryв режиме "авось". Поставил1(всегда обещай), система всем радостно кивала, а потом — бац! — и реальной памяти нет. Вот тут-то OOM Killer и начинает свою кровавую жатву.
Что делать, чтобы не охуеть от неожиданности? Ну, кроме как настраивать oom_score_adj для важных процессов (чтобы их убивали в последнюю очередь), надо ставить лимиты через cgroups и мониторить так, чтобы видеть проблему за километр. Выручает node_exporter для Prometheus — смотри на графики использования памяти и swap, ставь алерты пораньше, пока не стало поздно. А то потом будешь сам от себя охуевать, разгребая последствия.