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

 

今回は以上となります。プロセスが勝手に停止したけどアプリケーションログに何の手掛かりも無いような場合は参考にしてみてください。

RANKING
2020.10.12
2020.11.19
2020.12.23
2020.10.05
2020.11.25