Сегодня на повестке у нас с тобой OOM Killer.
Out of Memory Killer (OOM Killer) – это механизм ядра Linux, который освобождает оперативную память при ее исчерпании за счет принудительного завершения некоторых запущенных процессов.
Погнали разбираться это работает и как его можно обуздать.
Когда оперативная память в ос linux заканчивается, происходят забавные вещи, ядро вызывает «кракена» OOM Killer. В свою очередь «кракен» прогоняет процесс по определенным правилам и убивает его.
Бытует ошибочное мнение, что OOM Killer берет самый жирный процесс и киляет его. Это не так. Создатели этого механизма знатно упоролись.
OOM Killer использует достаточно сложный анализ и присваивает каждому процессу очки негодности (badness). При исчерпании памяти, будет убит именно самый негодный процесс. Некий естественный отбор. Процесс убивается сигналом SIGKILL и не предоставляет приложению корректно завершиться. Вызывается функция out_of_memory, а далее select_bad_process.
После убийства, в системном журнале появится строчка:
Out of Memory: Killed process 2256 (mysql) score 907 or sacrifice childА это уже не шутки. Если к тебе стал приходить OOM Killer, значит в какой-то момент на сервере, что-то
Очки негодности могут принимать значение от -1000 до +1000. Соответственно чем выше это значение, тем вероятнее, что процесс будет убит. А процесс со значением -1000 будет по логике — бессмертным.
Посмотреть репутацию процесса, можно командой:
cat /proc/<PID>/oom_scoreГде PID это идентификатор процесса, узнать можешь командой ps ax|grep postfix
В результатах ты увидишь число, к примеру: 826, это и есть очки негодности.
Если интересно как начисляются очки негодности, я вынес это в отдельный пост в телеграф, чтобы не валить тебя скучной теорией. Почитать можешь тут:
✅ Как вычисляются очки негодности?
TL;DR Если подытожить, то OOM Killer убьет самый «жирный» процесс, который наименее активен в системе и имеет самое короткое время жизни.
Как обуздать OOM Killer? 🔪
Можно вообще его отключить! Но по понятным причинам, это все равно что отключить жизненно важный орган у человека. Какое-то время он еще проживет, но потом обязательно сдохнет в kernel panic.
Отключается командой:
sudo echo 1 > /proc/sys/vm/panic_on_oomПо умолчанию 0 (то есть включено). Я ни разу не встречал, чтобы кто-то отключил этот функционал, но достаточно много раз сталкивался с забиваем костылей в сами процессы.
Можно повысить или понизить репутацию для процесса, добавив в файл oom_adj значение от -17 до +15. Для повышения репутации выполняем команду:
sudo echo -6 > /proc/<PID>/oom_adjНе забываем подставить в PID, идентификатор нужного процесса.
Для отключения OOM Killer для определенного процесса, выставляем репутацию -17. Теперь этот процесс в «домике» и его никакая собака не посмеет тронуть.
sudo echo -17 > /proc/<PID>/oom_adjНо если ты рестартанешь процесс, у него изменится PID. А репутация, которую ты ему уже накрутил, может примениться к совсем другому процессу таким же PID.
Также можно динамически определять PID процесса и менять ему репутацию. Закинуть это в крон и прыгать от счастья:
pgrep -f "/usr/sbin/sshd" | while read PID; do echo -17 > /proc/$PID/oom_adj; doneНо правильнее задать очки в самом systemd, в юните для сервиса, этот параметр:
[Service]Собственно это база. По опыту скажу так — если к тебе пришел OOM Killer, сервак можно смело перезагружать. Нихрена там уже не работает, несмотря на всякие очки и коэффициенты. Перезагрузиться будет намного эффективнее, чем пытаться поднять что-то. Поднял, а потом уже по горячим следам и логам, дебаж.
OOMScoreAdjust=-500
Поздравляю, ты только что прокачался еще на один уровень. Хорошего тебе понедельника, да и лёгкой рабочей недели! Увидимся! 🐾
tags: #linux
—
🟢 Подпишись: @bashdays