私たちのクラスターでは、新しいプロセスが大量のメモリを要求すると、ノードがダウンすることがありました。 OOMキラーが有罪のプロセスを殺すだけではない理由に戸惑いました。
その理由は、一部のプロセスが-17oom_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
OK、sshd、udevd、dhclientには意味がありますが、通常のユーザープロセスでも-17になることがわかります。そのユーザープロセスがOOMイベントを引き起こすと、それが強制終了されることはありません。これにより、OOMkilerは非常識になります。 NFS rpc.statd、cron、たまたま-17ではなかったものはすべて消去されます。その結果、ノードはダウンしています。
私はDebian6.0(Linux 2.6.32-3-AMD64)を持っています。
-17 oom_adj割り当ての動作をどこで制御するかを知っている人はいますか?
/etc/rc.local
からsshdとTorque momを起動すると、過保護な動作が発生する可能性がありますか?
それは、それを生成したプロセスから継承されます。 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でオーバーコミットを無効にします。
vm.overcommit_ratio=60
vm.overcommit_memory=2
メモリとスワップの量に応じて比率を修正する必要があります。
オーバーコミットが無効になると、カーネルは、過剰なメモリを割り当てようとしているプロセスにNULLを返すだけです。これにより、クラスターノードでのすべてのメモリクラッシュが解決されました。