プロセスが突然死んだときのOOM Killerの確認方法とプロセス停止を回避する方法 - プロセスが突然死んだときのOOM Killerの確認方法とプロセス停止を回避する方法 - aegif Labo Blog Alfresco
null プロセスが突然死んだときのOOM Killerの確認方法とプロセス停止を回避する方法
こんにちは。おおたにです。
今回はOOM Killerによるプロセス停止の確認方法と、OOM Killerによるプロセス停止を防ぐ方法を紹介したいと思います。以下、CentOS 7を例に説明します。
OOM Killerとは
Linux上で重要なアプリケーションのプロセスが突然死んだけど、アプリケーションのログを見ても何もエラーが出力されていない、という経験はありませんか?そのような場合、システムのメモリ枯渇によりOOM Killerがそのプロセスを停止させた可能性があります。
OOM Killerはシステムのメモリが足りなくなった時に、プロセス毎の優先度やスコアをもとにしてプロセスを殺し、システム全体が停止してしまうことを防ぐための機能です。
OOM Killerによるプロセス停止の確認
OOM Killerによるプロセス停止のログが/var/log/messages
に出力されるので、まずはそれを確認します。以下のようなログが出力されていれば、OOM Killerによってプロセスが殺されたということになります。
$ cat /var/log/messages | grep Kill
Nov 8 13:22:24 localhost kernel: Out of memory: Kill process 17143 (java) score 468 or sacrifice child
Nov 8 13:22:24 localhost kernel: Killed process 17143 (java), UID 1001, total-vm:7790724kB, anon-rss:4108910kB, file-rss:6822kB, shmem-rss:0kB
OOM Killerによるプロセス停止の回避
プロセス毎にOOM Killerによるプロセス停止の優先度を設定することができます。デフォルトは0で、優先度を-1000にすることでプロセス停止の対象外となります。また、プロセス毎にスコアが計算され、スコアが高いものから順にプロセス停止の対象となります。
プロセス毎の優先度は/proc/<PID>/oom_score_adj
、スコアは/proc/<PID>/oom_score
で確認できます。例えば、httpd(Apache HTTP Server)の優先度とスコアは以下のように確認します。以下の例では優先度が0でスコアも計算されており、プロセス停止の対象となりうることが分かります。
$ ps -ef | grep httpd
root 177 1 0 Nov08 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 178 177 0 Nov08 ? 00:00:03 /usr/sbin/httpd -DFOREGROUND
...
$ cat /proc/177/oom_score_adj
0
$ cat /proc/177/oom_score
154
優先度を変更するためには、上記パラメータを-1000にセットする必要があります。手動で、もしくはプロセス起動スクリプトで変更する場合は以下のようにセットします(プロセスIDは適宜取得する必要あり)。
$ echo -1000 > /proc/177/oom_score_adj
systemd(systemctl)を使って起動しているサービスでは、ユニットファイルの[Service]セクションにOOMScoreAdjust=-1000
オプションを追記するだけでOKです。例えばhttpdの場合は以下のような感じで設定します。ユニットファイル変更後にはsystemctl daemon-reload
でユニットファイルをリロードしてからサービスを再起動する必要があります。
$ systemctl status httpd ● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled) Active: active (running) since Sat 2020-11-07 00:39:14 UTC; 2 days ago
... $ vi/usr/lib/systemd/system/httpd.service ... [Service] ... OOMScoreAdjust=-1000 ...[Service]セクションに追記
... $ systemctl daemon-reload $ systemctl restart httpd
最後に、設定変更が反映されたことを確認します。優先度が-1000となり、スコアが計算されなくなっています。
$ ps -ef | grep httpd
root 257 1 0 02:20 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
apache 258 257 0 02:20 ? 00:00:00 /usr/sbin/httpd -DFOREGROUND
...
$ cat /proc/257/oom_score_adj
-1000
$ cat /proc/257/oom_score
0
今回は以上となります。プロセスが勝手に停止したけどアプリケーションログに何の手掛かりも無いような場合は参考にしてみてください。