在我们的集群中,当新进程需要太多的内存时,我们有时候会有节点closures。 我不明白为什么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 kiler疯狂。 NFS rpc.statd,cron,碰巧不是-17的东西都将被清除。 结果是节点closures。
我有Debian 6.0(Linux 2.6.32-3-amd64)。
有谁知道在哪里控制-17 oom_adj分配行为?
从/etc/rc.local启动sshd和Torque妈妈是否会导致过度保护行为?
它从产生它的过程inheritance而来。 如果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
编辑init脚本来改变启动过程结束时的值应该解决这个问题。
在我们的集群上,我们使用sysctl禁用overcommit:
vm.overcommit_ratio=60 vm.overcommit_memory=2
您应该根据您有多less内存和交换来修复比率。
一旦overcommit被禁用,内核只会返回NULL到正试图分配太多内存的进程。 它解决了集群节点上所有的内存崩溃。