vm.overcommit_memoryの構成の影響


41

CentOS 5.4(Linuxカーネル2.6.16.33-xenU)で不規則に実行されているVPS Webサーバー(月に1回程度、数週間または数週間かかる)は、oom-killerの起動により応答しなくなります。サーバーの監視では、通常はメモリ不足になります。

次のsysctl設定を使用して、オーバーコミットをより適切に管理するためのカーネルの構成について説明しているこのページを指すブログをいくつか読みました。

vm.overcommit_memory = 2
vm.overcommit_ratio = 80

これについての私の理解(間違っているかもしれませんが、明確にするための標準的な定義が見つかりません)は、これによりカーネルがスワップ+物理メモリの80%を超えてメモリを過剰に割り当てることを防ぎます。

しかし、私はまた、読んだことがあるいくつかのこのアプローチの批評家がいることを前提に、「むしろ、この場しのぎをしようとするよりも、あなたのシステムを破るために、物事をしない」と言っているように見えるが、 -これらの設定は良いアイデアではないことを示唆している他のソースを因果関係は常に知られています。

だから私の質問は、約10の低トラフィックサイトをホストしているApache2 Webサーバーのコンテキストで、このアプローチの長所と短所は何ですか?私の場合、Webサーバーには512MbのRAMがあり、1024Mbのスワップスペースがあります。これは、ほとんどの場合に適切であると思われます。

回答:


32

overcommit_ratio80に設定することは、おそらく正しいアクションではありません。値を100未満に設定することは、ほとんどの場合正しくありません。

これは、Linuxアプリケーションが実際に必要なものよりも多く割り当てるためです。テキストのカップル文字列を保存するために8kbを割り当てたとします。まあ、それは数KB未使用です。アプリケーションはこれを頻繁に行いますが、これがオーバーコミットの目的です。

したがって、基本的に100のオーバーコミットでは、カーネルはアプリケーションがあなたが持っている以上のメモリを割り当てることを許可しません(スワップ+ RAM)。100未満に設定すると、すべてのメモリが使用されることはありません。この設定を行う場合は、前述のシナリオのため、100より高い値に設定する必要があります。これは非常に一般的です。

現在、OOMキラートリガーの問題に関しては、手動でオーバーコミットを設定してもこの問題は解決しません。デフォルト設定(ヒューリスティック判定)はかなりインテリジェントです。

これが本当に問題の原因であるかどうかを確認したい場合は/proc/meminfo、OOMキラーが実行されるタイミングを確認してください。あなたはそれが表示された場合Committed_ASに近いですCommitLimitが、freeまだ空きメモリが利用可能に表示され、[はい、あなたは手動であなたのシナリオのオーバーコミットを調整することができます。この値の設定が低すぎると、メモリが十分にあるときにOOMキラーがアプリケーションの強制終了を開始します。設定が高すぎると、割り当てられたメモリを使おうとするとランダムなアプリケーションが停止する可能性がありますが、実際には使用できません(すべてのメモリが実際に使い果たされる場合)。


1
感謝-私は何が起こるか見るために100に設定されたovercommit_ratioで物事を試みています。私が抱える主な問題は、oom-killerを起動すると必ずsshdが強制終了され、サーバーにアクセスして何が起きているのかを確認できなくなることです。私が本当に必要なのは、oom-killerの実行を停止し、それが実行されたときに何が起こるかを記録する何らかの手段で、問題の原因を見つけることができると思います。
dunxd

4
/proc/<PID>/oom_score_adjこの目的で使用できる@dunxd 。たとえば、sshdのoom_score_adjを-1000に設定すると、oom killerは何かを殺したいときにsshdをターゲットにしません。oom killerを完全に停止するのは良い考えではありません。プログラムがメモリをmallocできなくなり、とにかく死んでしまうからです。
パトリック

4
@dunxdは継承されます。initスクリプトにそれを設定してもらい、initスクリプトによって開始されたものは何でもそれを継承します。
パトリック

4
4 KBの例は間違っています。仮想メモリはページで使用され、Linuxでのページの(最小)サイズは4 KBです。つまり、数文字を保存するには、オーバーコミット設定に関係なく4 KBをどこかにマップする必要があります。メモリのオーバーコミットの適切な例は、たとえば、10 KBを割り当て、最初の4100バイトのみを使用することです。つまり、2つの4 KBページでデータを保存する必要があり、1つの余分なページは使用されません。オーバーコミットしていないシステムでは、要求が到着した場合にデータを保存する準備ができた3ページ目が常にありますが、オーバーコミットしているシステムはそれを強制しません。
jlliagre

2
/ proc / selfは現在のプロセスを指しているため、/ proc / self / oom_score_adjを使用して、現在のプロセスのoom_score_adjを変更できます。
r_2 14

23

@dunxdが言及しているドキュメントのセクション9.6「オーバーコミットとOOM」は、オーバーコミットを許可する危険性について特に図解されています。しかし、80私にとっても面白そうだったので、いくつかのテストを行いました。

私が見つけたのは、これovercommit_ratioがすべてのプロセスで利用可能なRAMの合計に影響するということです。ルートプロセスは、通常のユーザープロセスとは異なる方法で扱われるようには見えません。

比率を100以下に設定すると、からの戻り値malloc/sbrkが信頼できる古典的なセマンティクスが提供されます。それよりも低い比率を設定する100と、キャッシュなどの非プロセスアクティビティ用により多くのRAMを予約できる可能性があります。

だから、スワップとRAMの24ジブ、と自分のコンピュータ上で、9ジブ使用中、使用不可にtop示します

Mem:  24683652k total,  9207532k used, 15476120k free,    19668k buffers
Swap:        0k total,        0k used,        0k free,   241804k cached

いくつかのovercommit_ratio設定と、RAM消費者プログラムが(各ページに触れて)取得できるRAMの量を以下に示しますmalloc。いずれの場合も、プログラムは失敗すると正常に終了しました。

 50    ~680 MiB
 60   ~2900 MiB
 70   ~5200 MiB
100  ~12000 MiB

一度に複数のユーザーを実行しても、一部がrootユーザーであっても、一緒に消費される合計量は変わりませんでした。興味深いのは、最後の3+ GiB程度を消費できなかったことです。freeずっとここに示されているものを下回りませんでした。

Mem:  24683652k total, 20968212k used,  3715440k free,    20828k buffers

多くのプログラマーはCでmallocの失敗をチェックするのがひどく、一部の一般的なコレクションライブラリはそれを完全に無視し、C ++や他のさまざまな言語も悪い。

私が見た架空のRAMの初期の実装のほとんどは、1つの大きなプロセス(たとえば、使用可能なメモリの51%以上)fork()exec()何らかのサポートプログラム(通常ははるかに小さいもの)をサポートするために必要な非常に特殊なケースを処理するものでした。copy-on-writeセマンティクスを備えたOS fork()ではが許可されますが、フォークされたプロセスが実際に多くのメモリページを変更しようとした場合は(ただし、各ページは最初の巨大なプロセスから独立した新しいページとしてインスタンス化される必要があります)殺されることになります。親プロセスは、より多くのメモリを割り当てる場合にのみ危険にさらされ、場合によっては他のプロセスが停止するのを少し待ってから続行することで、不足を処理できました。子プロセスは通常、それ自体を(通常はより小さい)プログラムに置き換えますexec() そして、但し書きはありませんでした。

Linuxのオーバーコミットの概念は、fork()単一のプロセスが大規模に全体的に割り当てられるようにするだけでなく、両方を発生させるための極端なアプローチです。OOMキラーに起因する死亡は、さらにプログラムに、非同期的に起こる行うハンドルのメモリ割り当ての責任を。私は個人的にはシステム全体のオーバーコミット全般、特にoom-killerが嫌いです。これは、ライブラリに感染するメモリ管理への悪魔のようなケアのアプローチを促進し、ライブラリを介してそれらを使用するすべてのアプリを促進します。

比率を100に設定することをお勧めします。また、スワップパーティションも同様に、通常は巨大なプロセスでしか使用されません。大部分のプロセスをOOMキラーの誤機能から保護します。これにより、ウェブサーバーがランダムに死ぬのを防ぎ、malloc責任を持って処理するように書かれている場合は、自分自身を殺すことからも安全に保つ必要があります(ただし、後者には賭けないでください)。

それは私がこれを使用していることを意味します /etc/sysctl.d/10-no-overcommit.conf

vm.overcommit_memory = 2
vm.overcommit_ratio = 100

また、vm.overcommit_memoryを2に維持することをお勧めしますか?
Ut xD

1
良いメモ-それは確かに私が使用しているものです。それはすでに質問にあるので、私は答えでそれを省略したと思う
アレックスノースキーズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.