Early OOM Daemon как альтернатива OOM Killer

()

Механизм OOM Killer призван спасать системы на базе Linux от нехватки памяти. Работает он достаточно просто: когда память заканчивается он на основе специального алгоритма вычисляет процесс, смерть которого причинит меньше всего вреда и даст больше всего сободной памяти и убивает его.

Этот механизм имеет спорную репутацию среди пользователей: с одной стороны ему практически нет альтернатив, с другой - он начинает работу в тот момент когда система уже давно и глубоко заторможена «сидением в подкачке». В качестве альтернативы OOM Killer разрабатывается Early OOM Daemon, о котором и пойдёт речь далее.

В Ubuntu 18.04 Early OOM Daemon присутсвует в стандартном репозитории и его можно установить командой:

apt-get install earlyoom

Early OOM Daemon не имеет файла настроек и желаемые опции ему надо передавать в виде параметров командой строки. Описать их можно в файле «/etc/default/earlyoom». В этом файле есть некоторое количество примеров, достаточных для базовой настройки. Кроме того достаточно информативна man-страница сервиса. Прежде чем написать свою конфигурацию рассмотрим основные параметры:

  • -m: количество свободной памяти в процентах, при котором необходимо начинать чистку.
  • -s: количество свободной «подкачки» в процентах при котором необходимо начинать чистку.
  • -M: аналогично -m, но размер в кибибайтах (KiB, 1 KiB = 1024 bytes).
  • -S: аналогично -s, но размер в кибибайтах (KiB).
  • --prefer: регулярное выражение, описывающее процессы, которые стоит убивать в первую очередь.
  • --avoid: регулярное выражение, описывающее процессы, которые стоит убивать в последнуюю очередь.
  • -N: команда, используемая для отправки нотификаций в случае срабатывания сервиса.

Здесь есть интересный момент: параметр -N расчитан на работу совместно с утилитой notify-send из пакета «libnotify-bin» и запускает команду примерно так:

COMMAND -l dialog-warning earlyoom "Killing process 10977 Web Content"

И отсюда начинаются проблемы: так как сам сервис работает от пользователя root и не имеет доступа к пользовательской сессии то необходимо придумать какой-то обходной манёвр. Автор этих строк тестировал earlyroom на дистрибутиве Lubuntu 18.04, работая под учётной записью с именем «moose» и в итоге был написал скрипт «/home/moose/scripts/earlyoom-notify.sh» следующего содержания:

#!/bin/bash

if [ "$#" -ne "4" ]; then
        echo "Illegal params number"
        exit
fi

RUNASUSER="moose"

WHOAMI=`whoami`
if [ ${WHOAMI} != ${RUNASUSER} ]; then
        su -c "$0 \"$1\" \"$2\" \"$3\" \"$4\"" ${RUNASUSER}
        exit
fi

DISPLAY=:0 notify-send "$1" "$2" "$3" "$4"

Этот скрипт по сути является обёрткой для notify-send и просто запускает notify-send в нужном окружении.

В файле «/etc/default/earlyoom» конфигурация была описана следующим образом:

EARLYOOM_ARGS="-m 5 -s 60 --prefer '(^|/)(firefox|thunderbird)$' --avoid '(^|/)(sshd|systemd|init)' -N /home/moose/scripts/earlyoom-notify.sh"

Разумеется после изменения этих настроек необходимо перезапустить сервис командой:

service earlyoom restart

В описаной конфигурации чистка памяти запускается когда остаётся менее 5% свободной оперативной памяти и менее 60% места на разделе подкачки. Первыми целями являются браузер и почтовый клиент, а последними - системные сервисы. При закрытии приложения будет показано сообщение в углу экрана.

Сообщение от Early OOM Daemon

При использовании на сервере стоит подкорректировать регулярные выражения в параметрах в зависимости от особенностей сервера. Скрипт нотификаций можно переписать чтобы он отправлял почту администраторам. Например так:

#!/bin/bash

if [ "$#" -ne "4" ]; then
        echo "Illegal params number"
        exit
fi

echo $4 | mail -s "$3" admins@example.com

Если попыткаться кратко описать различие между OOM Killer и Early OOM Daemon то можно сказать следующее: OOM Killer это механизм, обеспечивающий защиту систему в критичной ситуации, а Early OOM Daemon это скорее способ избежать критичной ситуации.

На этом всё, приятной работы!

Ключевые слова: earlyoom, oom killer.

Подписаться на обновления: RSS-лента Канал в TamTam Telegram канал Канал в ICQ

Комментарии:

Anonymous 2020-01-05 19:49:58 (#)

--avoid '(^|/)(sshd|systemd|init)'
не надо ли в конце $ перед апострофом ?
в дебе еще по умолчанию X стоят

MooSE 2020-01-05 23:02:25 (#)

не надо ли в конце $ перед апострофом ?
Можно. Но не обязательно
Новый комментарий

Жирный текстКурсивный текстПодчёркнутый текстЗачёркнутый текстПрограммный кодСсылкаИзображение




© 2006-2024 Вадим Калинников aka MooSE
Политика конфиденциальности