OOM 杀手疯了

OOM 杀手疯了

在我们的集群中,当新进程请求过多内存时,有时会出现节点宕机的情况。我很困惑,为什么 OOM 终止程序不直接终止有问题的进程。

原因是有些进程的 oom_adj 为 -17。这导致它们无法被 OOM killer 杀死(无法杀死!)。

通过以下脚本我能够清楚地看到这一点:

#!/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会导致过度保护行为?

答案1

它从生成它的进程继承而来。如果 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

编辑初始化脚本来改变启动过程结束时的值应该可以解决这个问题。

答案2

在我们的集群上,我们使用 sysctl 禁用过度提交:

vm.overcommit_ratio=60
vm.overcommit_memory=2

您应该根据内存和交换空间的大小来确定该比例。

一旦禁用过度使用,内核就会向试图分配过多内存的进程返回 NULL。它解决了集群节点上的所有内存崩溃问题。

相关内容