В нашем кластере узлы иногда выходили из строя, когда новый процесс запрашивал слишком много памяти. Я был озадачен, почему убийца OOM не просто убивает виновных.
Причина оказалась в том, что некоторые процессы получают -17 oom_adj. Это делает их недоступными для OOM-убийцы (unkillabe!).
Я ясно вижу это с помощью следующего сценария:
#!/bin/bash
for i in `grep -v 0 /proc/*/oom_adj | awk -F/ '{print $3}' | grep -v self`; do
ps -p $i | grep -v CMD
done
Хорошо, это имеет смысл для sshd, udevd и dhclient, но потом я вижу, что обычные пользовательские процессы также получают -17. Как только этот пользовательский процесс вызывает событие OOM, он никогда не будет убит. Это приводит к тому, что убийца OOM сходит с ума. NFS rpc.statd, cron, все, что оказалось не -17, будет уничтожено. В результате узел не работает.
У меня Debian 6.0 (Linux 2.6.32-3-amd64).
Кто-нибудь знает, где контролировать поведение присваивания -17 oom_adj?
Мог запустить sshd и Torque mom из /etc/rc.local
вызывать чрезмерное защитное поведение?
В наших кластерах мы отключаем чрезмерную фиксацию с помощью sysctl:
vm.overcommit_ratio=60
vm.overcommit_memory=2
Вы должны исправить соотношение в зависимости от того, сколько у вас памяти и свопа.
После отключения overcommit ядро просто возвращает NULL процессу, который пытается выделить слишком много памяти. Это решило все сбои нашей памяти на узлах кластера.
Он унаследован от процесса, который его породил. Если для SSH установлено значение -17, то Bash будет. Если вы перезапустите через Bash, вы создадите его еще дальше.
[i-180ae177] root@migrantgeek ~ # pgrep mysqld_safe
11395
[i-180ae177] root@migrantgeek ~ # cat /proc/11395/oom_adj
0
[i-180ae177] root@migrantgeek ~ # for pid in `pgrep bash`; do echo -17 > /proc/$pid/oom_adj; done
[i-180ae177] root@migrantgeek ~ # /etc/init.d/mysqld restart
Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]
[i-180ae177] root@migrantgeek ~ # pgrep mysqld_safe
11523
[i-180ae177] root@migrantgeek ~ # cat /proc/11523/oom_adj
-17
Редактирование сценария инициализации для изменения значения в конце процесса запуска должно исправить это.