Linuxのメモリ不足キラーの設定方法

Robert Chase氏により
、2013年2月に公開

この記事では、Linuxのメモリ不足(OOM)キラーと、特定のプロセスが強制終了された原因を調べる方法について説明します。また、さまざまな環境のニーズに合わせてOOMキラーを構成する方法もご提供します。

OOMキラーについて

データベースまたはアプリケーションサーバーをサポートしているサーバーがダウンした場合、それが特に重要なプロダクションシステムだと、重要なサービスを復旧して稼働させることはしばしば急ぎになります。最初のトリアージ後に根本原因を特定しようとするとき、アプリケーションまたはデータベースが突然機能を停止した原因については、多くの場合分かりません。特定の状況では、問題の根本的な原因はシステムのメモリ不足で、運用を継続するために重要なプロセスが強制終了するというものです。

Linuxカーネルは、システムで実行されているアプリケーションの要求に応じてメモリを割り当てます。多くのアプリケーションは事前にメモリを割り当て、割り当てられたメモリは利用しないことが多いため、カーネルはメモリをオーバーコミットしてメモリの使用効率を高める機能を備えて設計されています。このオーバーコミットモデルにより、カーネルは実際に物理的に利用可能なメモリよりも多くのメモリを割り当てることができます。プロセスが割り当てられたメモリを実際に使用する場合、カーネルはこれらのリソースをアプリケーションに提供します。割り当てられたメモリの利用を始めるアプリケーションが多すぎると、オーバーコミットモデルに問題が発生することがあり、カーネルは動作継続のためにプロセスの強制終了を開始しなければなりません。カーネルがシステム上のメモリを回復するために使用するメカニズムは、メモリ不足キラーまたは略してOOMキラーと呼ばれています。

プロセスが強制終了された原因の確認

アプリケーションがOOMキラーによって強制終了された問題をトラブルシューティングする場合、プロセスが強制終了された方法と原因を明らかにする手がかりがいくつかあります。次の例では、syslogを見て、問題の原因を特定できるかどうかを確認します。oracleプロセスは、メモリ不足状態が原因でOOMキラーによって強制終了されました。キャピタルKは、Killedにあり、-9でプロセスが強制終了されたことを示しますが、これは通常、OOMキラーが犯人である可能性があることを示す良い兆候です。




grep -i kill /var/log/messages*
host kernel: Out of Memory: Killed process 2592 (oracle).


また、システムのメモリ使用量が少ない場合と多い場合のステータスを調べることもできます。これらの値はリアルタイムであり、システムのワークロードに応じて変化することに注意することが重要です。したがって、これらはメモリ不足が発生する前に頻繁に監視していなければなりません。プロセスが強制終了された後にこれらの値を確認することは、あまりにも洞察力に欠けるため、OOMの問題の調査には役立ちません。




[root@test-sys1 ~]# free -lm
             total       used       free     shared    buffers     cached
Mem:           498         93        405          0         15         32
Low:           498         93        405
High:            0          0          0
-/+ buffers/cache:         44        453
Swap:         1023          0       1023


このテスト仮想マシンでは、498MBの空きメモリが不足しています。システムはスワップを使用していません。-lスイッチは、ハイおよびローメモリの統計を表示して、-mスイッチは出力をメガバイト単位にして、読みやすくします。




[root@test-sys1 ~]# egrep 'High|Low' /proc/meminfo
HighTotal:             0 kB
HighFree:              0 kB
LowTotal:         510444 kB
LowFree:          414768 kB

同じデータは、/proc/memoryを調べて、特に高値と安値を確認することで得られます。ただし、この方法だと出力からスワップ情報は取得せず、出力はキロバイト単位です。

低メモリは、カーネルが直接物理的にアクセスできるメモリです。ハイメモリは、カーネルが直接の物理アドレスを持たないメモリであるため、仮想アドレスを介してマップする必要があります。古い32ビットシステムでは、メモリを仮想アドレスにマップする方法が原因で、ローメモリとハイメモリが表示されます。64ビットプラットフォームでは、仮想アドレススペースは不要で、すべてのシステムメモリがローメモリとして表示されます。

/proc/memoryを見ながら、freeコマンドを使用すると、「現在」のメモリ使用量を知るのに役立ちます。もっと長い期間のメモリ使用量を確認したい場合もあります。vmstatコマンドはこういった場合に非常に便利です。

リスト1の例では、vmstatコマンドを45秒ごとにリソースを10回確認するのに使用しています。-Sスイッチはテーブルにデータを表示、-Mスイッチは読みやすくするためにメガバイト単位で出力を表示します。ご覧のとおり、何かが空きメモリを消費していますが、この例ではまだスワップしていません。




[root@localhost ~]# vmstat -SM 45 10
procs -----------memory-------- ---swap-- -----io-- --system-- ----cpu---------
 r  b   swpd  free  buff  cache  si   so   bi   bo   in    cs us  sy  id  wa st
 1  0      0   221   125     42   0    0    0    0   70     4  0   0  100  0  0
 2  0      0   192   133     43   0    0  192   78  432  1809  1  15   81   2 0
 2  1      0    85   161     43   0    0  624  418 1456  8407  7  73    0  21 0
 0  0      0    65   168     43   0    0  158  237  648  5655  3  28   65   4 0
 3  0      0    64   168     43   0    0    0    2 1115 13178  9  69   22   0 0
 7  0      0    60   168     43   0    0    0    5 1319 15509 13  87    0   0 0
 4  0      0    60   168     43   0    0    0    1 1387 15613 14  86    0   0 0
 7  0      0    61   168     43   0    0    0    0 1375 15574 14  86    0   0 0
 2  0      0    64   168     43   0    0    0    0 1355 15722 13  87    0   0 0
 0  0      0    71   168     43   0    0    0    6  215  1895  1   8   91   0 0


リスト1

vmstatの出力は、次のコマンドを使用してファイルにリダイレクトできます。もっと長く監視するために、期間と回数を調整することもできます。コマンドの実行中、いつでも出力ファイルを確認して結果を確認できます。

次の例では、120秒ごとに1000回メモリを調べています。行最後の&により、これをプロセスとして実行して、ターミナルを取り戻すことができます。

vmstat -SM 120 1000 > memoryusage.out &

参考までに、リスト2はコマンドが提供する出力に関する追加情報を提供するvmstatのmanページにあるセクションを表示しています。これはメモリ関連の情報のみです。このコマンドは、ディスクI / OとCPU使用率の両方に関する情報も提供します。




   Memory
       swpd: the amount of virtual memory used.
       free: the amount of idle memory.
       buff: the amount of memory used as buffers.
       cache: the amount of memory used as cache.
       inact: the amount of inactive memory. (-a option)
       active: the amount of active memory. (-a option)

   Swap
       si: Amount of memory swapped in from disk (/s).
       so: Amount of memory swapped to disk (/s).

リスト2

この種の問題を調査するために、メモリとシステムのパフォーマンスを監視するのに利用できるツールが帆亜kにもたくさんあります。sar(システムアクティビティレポーター)およびdtrace(動的トレース)などのツールは、時間の経過に伴うシステムパフォーマンスに関する特定のデータの収集に非常に役立ちます。さらに視認性を高めるため、dtrace安定性プローブとデータ安定性プローブには、OOM状態が原因でカーネルがプロセスを強制終了した場合に起動するOOM状態用のトリガーもあります。dtracesarの詳細については、にあります。この記事のセクションもご覧ください。

ワークロードが原因でシステムのRAMが不足し、スワップ領域が使用可能になること以外に、OOM生涯を引き起こす可能性のあるものがいくつかあります。システムのワークロードのタイプが原因で、カーネルがスワップ領域を最適に利用できない場合があります。mlockを利用するアプリケーション()またはHugePagesには、システムの物理メモリが不足し始めたとき、ディスクにスワップできないメモリがあります。カーネルデータ構造は、システム上のメモリを使い果たしてOOM状態を引き起こし、スペースを占有してしまう可能性もあります。多くのNUMAアーキテクチャベースのシステムでは、メモリが不足すると1つのノードがカーネルでOOMをトリガーしますが、残りのノードには十分なメモリが残っているため、OOM状態が発生する可能性があります。NUMAアーキテクチャーを備えたマシンのOOM状態に関する詳細は、にあります。また、この記事のセクションもご覧ください。

OOMキラーの構成

LinuxのOOMキラーにはいくつかの構成オプションがあり、開発者はシステムのメモリ不足状態に直面した場合にシステムが示す動作を選択できます。これらの設定と選択肢は、システムが構成した環境とアプリケーションによって異なります。

: 重要なプロダクションシステムに変更を加える前に、開発環境でテストとチューニングを行うことを推奨しています。

一部の環境では、システムが重要なタスクを1つ実行しているとき、システムがOOM状態に陥り再起動することが、管理者の介入なくシステムを迅速に稼働状態に戻すための実行可能なオプションになる場合があります。最適なアプローチではありませんが、この背後にあるロジックは、アプリケーションがOOMキラーによって強制終了されたために動作できない場合、システムが再起動されれば、起動時にシステムから起動するとアプリケーションが復元されます。アプリケーションが管理者によって手動で開始された場合、このオプションにメリットはありません。

次の設定は、システムのパニックの原因になり、メモリ不足の状態で再起動してしまいます。sysctlコマンドはこれをリアルタイムで設定し、設定をsysctl.confに追加することでこれらの設定が再起動後も存続できます。Xは、kernel.panicのためで、システムを再起動されるまでの秒数です。この設定は、環境のニーズに合わせて調整する必要があります。




sysctl vm.panic_on_oom=1
sysctl kernel.panic=X
echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
echo "kernel.panic=X" >> /etc/sysctl.conf


また、OOMキラーが特定のプロセスでOOM状態を処理する方法を調整することもできます。以前に強制終了されたoracleプロセス2592を例にとってみてください。OOMキラーによって強制終了可能性が低いoracleプロセスを作りたい場合、次のようにすることができます。

echo -15 > /proc/2592/oom_adj

次の手順で、oracleプロセスを強制終了する可能性が高いOOMキラーを作れます。

echo 10 > /proc/2592/oom_adj

除外したい場合oracleプロセスを除外したい場合、次のことを実行すれば、OOMキラーから完全に除外されます。システムのリソースと構成によっては、予期しない動作を引き起こす可能性があることに注意することが重要です。カーネルが大量のメモリを使用していてプロセスを強制終了できない場合、他の使用可能なプロセスに移行します。これらのプロセスの一部は、最終的にシステムを停止させる可能性のある重要なオペレーティングシステムプロセスかもしれません。

echo -17 > /proc/2592/oom_adj

oom_adjの有効範囲を設定できます。-16から+15に設定でき、-17の設定は、プロセスを完全にOOMキラーから免除します。システムでOOM状態が発生すると、その数値が大きいほど、プロセスが終了に選択される可能性が高くなります。/proc/2592/oom_scoreの内容も、プロセスがOOMキラーによって強制終了される可能性の判断のために表示できます。0のスコアは、プロセスがOOMキラーから免除されることを示しています。OOMスコアが高いほど、OOM状態でプロセスが強制終了される可能性が高くなります。

OOMキラーは次のコマンドで完全に無効にすることができます。これは、実稼働環境では推奨されません。メモリ不足状態が発生した場合、使用可能なシステムリソースと構成によっては予期しない動作が発生する場合があるためです。この予期しない動作は、OOM状態のときにカーネルが使用できるリソースに応じて、カーネルパニックからハングアップまでさまざまです。




sysctl vm.overcommit_memory=2
echo "vm.overcommit_memory=2" >> /etc/sysctl.conf

一部の環境では、これらの構成オプションは最適ではなく、さらにチューニングと調整が必要になる場合があります。カーネルにHugePagesを設定すると、システムで実行されているアプリケーションのニーズに応じて、OOMの問題を解決できます。

こちらもご覧ください

HugePagesに関する追加のリソースをいくつかご紹介します。dtracesar、NUMAアーキテクチャのOOM:

著者について

Robert Chase氏は、Oracle Linux製品管理チームのメンバーです。彼は1996年からLinuxとオープンソースソフトウェアに携わっています。組み込みデバイスと同じくらい小さなシステムと、大規模なスーパーコンピュータークラスのハードウェアの仕事をしてきました。

Revision 1.0, 02/19/2013