The No Hang Daemon
Nohang - аналог earlyoom с поддержкой zram и SIGTERM. При дефиците доступной памяти nohang корректно завершает наиболее прожорливые процессы сигналом SIGTERM, тем самым препятствуя зависанию, а также избыточному убийству процессов ядерным OOM killer'ом.
Зачем это нужно?
Затем, что этот демон реализует востребованный функционал. Судите сами:
"А можете рассказать, как сделать OOM Killer более агрессивным? Например, в ситуации, когда приложение открыло/создало множество мелких файлов и держит их в памяти, при внезапной нехватке памяти ядро пытается высвободить эти файловые страницы, что вешает систему намертво со 100%-м дисковым I/O на несколько (десятков) минут. А ведь зачастую гораздо проще просто грохнуть само приложение с дальнешим его перезапуском." https://habr.com/company/flant/blog/348324/#comment_10659202
"Говно какое-то этот оом-киллер, нихрена не работает. Но чтобы это нормально работало, я думаю, нужен какой-то демон, который постоянно мониторит потребление памяти и прибивает тот процесс, который резко начинает набирать обороты. В общем сам этот демон будет проц грузить, хотя можно ограничить процессы, которые он будет проверять только пользовательскими процессами, добавить black-white list ну и настраиваемый интервал проверки. Короче если кто-то напишет будет круто." https://www.linux.org.ru/forum/general/13074074#comment-13074864
"Сегодня скормил пикарду 100-дисковое издание Бетховена и тот сожрал 16 гб памяти вместе с 8 гб zram (коэффициент сжатия был 3.5). Со swappiness 100 zram начал наполняться на 80% памяти, а когда сам достиг 80%, то сжатие продолжилось с новой силой и полной загрузкой ядра. По окончанию банкета система встала колом, потому что киллер опять сцуко не пришел (ждал 10 минут)." https://www.linux.org.ru/forum/general/13074074/page1?lastmod=1481740875388#comment-13077387
"Система таки становится неюзабельной если продолжать стараться забивать ее вплоть до исчерпания RAM+ZRAM. Ничего неудивительного, памяти то нет. Но в случае с дисковым свопом ты начинаешь заранее замечать что дело плохо. По ощущениям ZRAM не тормозит вообще, потому ты ничего не подозреваешь до часа икс и система становится колом." https://www.linux.org.ru/forum/talks/12684213?lastmod=1466676523241#comment-12684906
"И IRL ты никогда не знаешь, в какой момент момент твои данные перестанут умещаться в оперативку. Потому zram -- удел embedded систем, где это может быть детерминировано." https://2ch.hk/s/res/2310304.html#2311483, https://archive.li/idixk
Nohang позволяет избавиться от перечисленных выше проблем, корректно завершая наиболее прожорливые процессы сигналом SIGTERM не дожидаясь когда система "встанет колом". Nohang позволяет не бояться зависаний при использовании zram.
Зачем нужен nohang, если уже есть earlyoom?
earlyoomзавершает (точнее убивает) процессы исключительно с помощью сигналаSIGKILL, в то время какnohangдает возможность сначала отправлятьSIGTERM, и только если процесс не реагирует наSIGTERM- отправляется сигналSIGKILL.earlyoomне поддерживает работу соzramи не реагирует на общую долюzramв памяти (mem_used_total). Это может привести к тому, что система все также встанет колом, как если быearlyoomи не было (еслиdisksizeбольшой, а энтропия сжимаемых данных велика).Nohangпозволяет избавиться от этой проблемы. По умолчанию если доляzramдостигнет 60% памяти - будет отправлен сигналSIGTERMпроцессу с наибольшимoom_score.
Особенности
- задача - препятствовать зависанию системы при нехватке доступной памяти, а также корректное завершение процессов с целью увеличения объема доступной памяти
- демон на Python 3, VmRSS около 12 MiB
- требуется
Linux 3.14+иPython 3.4+ - периодически проверяет размеры доступной памяти, при дефиците памяти отправляет
SIGKILLилиSIGTERMпроцессу с наибольшимoom_score - поддержка работы со
zram, возможность реакции наmem_used_total - удобный конфиг с возможностью тонкой настройки
- аргументы командной строки -h/--help и -c/--config
- возможность раздельного задания уровней
MemAvailable,SwapFree,mem_used_totalдля отпракиSIGTERMиSIGKILL, возможность задания в процентах (%), кибибайтах (K), мебибайтах (M), гибибайтах (G) - возможность снижения
oom_score_adjпроцессов, чьиoom_score_adjзавышены (актуально дляchromium) - лучший алгоритм выбора периодов между проверками доступной памяти: при больших объемах доступной памяти нет смысла проверять ее состояние часто, поэтому период проверки уменьшается по мере уменьшения размера доступной памяти
- интенсивность мониторинга можно гибко настраивать (параметры конфига
rate_mem,rate_swap,rate_zram) - по умолчанию память заблокирована с помощью
mlockall()для предотвращения своппинга процесса - по умолчанию высокий приоритет процесса
nice -20, может регулироваться через конфиг - предотвращение самоубийства с помощью
self_oom_score_adj = -1000 - возможность задания
oom_score_minдля предотвращения убийства невиновных - verbosity: опциональность печати параметров конфига при старте программы, опциональность печати результатов проверки памяти
- возможность предотвращения избыточного убийства процессов с помощью задания миниального
oom_scoreдля убиваемых процессов и установка минимальной задержки просле отправки сигналов (параметры конфигаmin_delay_after_sigkillиmin_delay_after_sigterm) - наличие
manстраницы - наличие установщика для пользователей
systemd - протестировано на
Debian 9 x86_64,Debian 8 i386,Fedora 28 x86_64 - пример вывода с отчетом об успешной отпраке сигнала:
MemAvail: 0M 0.0%, SwapFree: 706M 6.0%, MemUsedZram: 357M 6.1%
MemAvail: 0M 0.0%, SwapFree: 411M 3.5%, MemUsedZram: 362M 6.2%
+ MemAvail (0M, 0.0%) < mem_min_sigterm (235M, 4.0%)
SwapFree (411M, 3.5%) < swap_min_sigterm (470M, 4.0%)
Try to send signal 15 to python3, Pid 3930, oom_score 903
Success
MemAvail: 107M 1.8%, SwapFree: 3461M 29.5%, MemUsedZram: 311M 5.3%
MemAvail: 5159M 87.8%, SwapFree: 11311M 96.3%, MemUsedZram: 186M 3.2%
Установка и удаление для пользователей systemd
git clone https://github.com/hakavlad/nohang.git
cd nohang
Установка
sudo ./install.sh
Удаление вместе с конфигом
sudo ./purge.sh
Удалить всё, кроме конфига
sudo ./uninstall.sh
Настройка
Nohang настраивается с помощью конфига, расположенного после установки
по адресу
/etc/nohang/nohang.conf
К опциям прилагается описание. Отредактируйте значения параметров в соответствии с вашими предпочтениями и перезапустите сервис командой sudo systemctl restart nohang.
Почему Python, а не C?
- Скорость разработки на Python значительно выше. Больше фич за приемлемое время.
- Практически единственный минус Python - большее потребление памяти процессом.
Известные баги
В рабочем алгоритме известных нет, если найдете - пишите в Issues.