Linux OOMキラーをデフォルトでオフにしますか?


37

LinuxのOOMキラーは、さまざまなアプリケーションで大混乱を引き起こしますが、これを改善するためにカーネル開発側で実際に行われていることはあまりないようです。新しいサーバーをセットアップする際のベストプラクティスとして、メモリのオーバーコミットのデフォルトを元に戻す、つまりvm.overcommit_memory=2、特定の用途でオンにする必要があることがわかっていない限り、オフ()にすると良いでしょうか?そして、これらのユースケースは、オーバーコミットをしたいことがわかっている場合はどうなりますか?

ボーナスとして、この場合の動作はスワップスペースにvm.overcommit_memory=2依存するvm.overcommit_ratioため、この2つのセットアップ全体が合理的に機能し続けるように、後の2つのサイズを決定するための良い経験則は何でしょうか?

回答:


63

興味深いアナロジー(http://lwn.net/Articles/104179/から):

航空機会社は、より少ない燃料で飛行機を飛ばす方が安いことを発見しました。飛行機はより軽くなり、より少ない燃料とお金が節約されました。しかし、まれに燃料の量が不足し、飛行機がcrash落することがありました。この問題は、特別なOOF(燃料切れ)メカニズムの開発により、会社のエンジニアによって解決されました。緊急の場合、乗客が選択され、飛行機から投げ出されました。(必要に応じて、手順が繰り返されました。)大量の理論が開発され、多くの出版物が、排出される犠牲者を適切に選択する問題に専念しました。犠牲者はランダムに選ばれるべきですか?または、最も重い人を選ぶべきですか?それとも最古?乗客が退出しないように支払う必要がある場合、被害者が船上で最貧になるように?そして、例えば最も重い人が選ばれた場合、それがパイロットだった場合に特別な例外があるべきでしょうか?ファーストクラスの乗客は免除されるべきですか?OOFメカニズムが存在するようになったため、時々作動し、燃料不足がなくても乗客を追い出しました。エンジニアは、この誤動作の原因を正確に調査しています。


11
それを掘り出してくれてありがとう。
ニックボルトン

32

OOMキラーは、システムが過負荷になった場合にのみ大混乱をもたらします。それに十分なスワップを与えて、突然大量のRAMを食べることに決めたアプリケーションを実行しないでください。そうすれば問題はありません。

質問に具体的に答えるには:

  • 一般的な場合にオーバーコミットをオフにするのは良い考えだとは思いません。brk(2)(およびそれを使用するラッパーなど)を適切に処理するために記述されたアプリケーションはほとんどありません。mallocエラーを返す(3)。私が以前の仕事でこれを試したとき、OOMの結果を処理するだけではなく、メモリ不足エラーを処理できるすべてのものを取得するのは面倒であると考えられました(この場合、 OOMが発生した場合に臨時のサービスを再起動するよりもはるかに悪かった-GFSは大量の糞便であるため、クラスタ全体を再起動する必要がありました。
  • メモリをオーバーコミットするすべてのプロセスに対してオーバーコミットする必要があります。ここで最もよくある2つの犯人は、ApacheとJVMです。しかし、多くのアプリが多少なりともこれを行います。彼らは、将来のある時点で多くのメモリ必要になると考えているため、すぐに大きな塊を取得します。オーバーコミットが有効になっているシステムでは、カーネルは「なんでも、実際にそれらのページに書き込みたいときにわざわざ来る」ことになり、何も悪いことは起こりません。オーバーコミットオフシステムでは、カーネルは「いいえ、そんなに多くのメモリを確保することはできません。将来のある時点ですべてを書き込むと、骨が折れるので、メモリがありません!」と言います。そして、割り当ては失敗します。以来何も「ああ、OK、このより少ないプロセスデータセグメントを使用できますか?」、そしてプロセスは(a)メモリ不足エラーで終了するか、(b)からのリターンコードをチェックしませんmallocは、実行しても問題ないと考え、無効な​​メモリの場所に書き込み、セグメンテーション違反を引き起こします。ありがたいことに、JVMは起動時にpreallocのすべてを実行します(したがって、JVMはすぐに起動するか、通常はすぐに終了します)。 「興奮の種類)。
  • overcommit_ratioをデフォルトの50%より高く設定したくないでしょう。ここでも、私のテストから、80または90かもしれないのまわりでそれを設定するものの、クールのアイデアのように、カーネルは不便なタイミングでメモリの大きな塊を必要とし、高いオーバーコミット比で完全にロードされたシステムは、おそらく十分な予備のメモリを持つことですカーネルがそれを必要とするとき(恐怖、疫病、おっとにつながる)。したがって、オーバーコミットで遊ぶと、新しい、さらに楽しい障害モードが導入されます。メモリが不足したときにOOMになったプロセスを単に再起動するのではなく、マシンがクラッシュし、マシン上のすべてが停止します。驚くばかり!
  • オーバーコミットのないシステムのスワップ領域は、アプリケーションに必要な未使用の要求メモリの量と健全な安全マージンに依存します。特定のケースで必要なものを理解することは、読者の課題として残されています。

基本的に、私の経験では、オーバーコミットをオフにすることは、理論的には実際に機能することはめったにない素晴らしい実験です。これは、カーネル内の他の調整可能パラメータに関する私の経験とうまく一致します-Linuxカーネル開発者はほとんど常にあなたよりも賢く、デフォルトは広大で多数の場合に最適に機能します。それらをそのままにして、代わりにどのプロセスにリークがあるかを見つけて修正してください。


2
誰かが私のWebサーバーをDoS攻撃しているので、バックアッププロセスを強制終了させたくありません。例外は問題ありませんが、デフォルトでは安全性と一貫性が必要です。OOMなどの最適化を手動で有効にする必要があります。それはコーディングのようなもので、きれいにコーディングしてから最適化します。オーバーコミットは素晴らしい機能ですが、デフォルトではないはずです。
アキ

1
誰かがWebサーバーをDoSしているためにバックアッププロセスを強制終了させたくない場合は、DoSによってシステム上のリソースが圧倒されるような方法でWebサーバーを構成しないでください。
ウォンブル

8GBのRAMがあり、Firefoxと仮想マシンを実行するだけで、OOMキラーがVMを殺すことがあります。Unreal Engine 4をコンパイルすると、各clang呼び出しは1〜1.5GBのメモリを消費し、OOMキラーは時々1つを殺します。現在、私はそれで大丈夫です。OOMキラーがなければ、おそらくセグメンテーション違反になります。それは、OOMキラーがプロセスを強制終了するたびに、悪いプロセスが実際に強制終了される前にシステムが10分間フリーズするだけです。おそらくバグ?最も可能性が高い。欲しい?絶対にありません。そして、それがOOMキラーを無効にしたい理由です。
シャーバズ

1
ボックス上でこれらすべてを実行する場合、より多くのRAMが必要であり、オーバーコミットを無効にすると悪化するだけです。
ベンルトゲンス

6

うーん、私はオーバーコミットとOOMキラーを支持する議論に完全に納得していません... wombleが書いているとき、

「OOMキラーは、システムが過負荷になった場合にのみ大混乱をもたらします。十分なスワップを与え、突然大量のRAMを食べることにしたアプリケーションを実行しないでください。問題はありません。」

彼は、オーバーコミットとOOMキラーが強制されない、または「本当に」行動しない環境シナリオについて説明しています(すべてのアプリケーションが必要に応じてメモリを割り当て、割り当てられる仮想メモリが十分にある場合、メモリの書き込みはエラーのため、オーバーコミット戦略が有効になっていても、オーバーコミットされたシステムについては本当に話せませんでした)。これは、オーバーコミットとOOMキラーが介入が必要ないときに最も効果的に機能するという暗黙の承認に関するものです。これは、この戦略のほとんどの支持者が何らかの形で共有しています(私が伝えることができる限りでは...)Moroverは、メモリを事前に割り当てる際に特定の動作を持つアプリケーションを参照すると、特定の処理をデフォルトではなく分散レベルで調整できると思うようになり、

JVMが懸念しているのは、仮想マシンです。起動時に必要なすべてのリソースをある程度割り当てる必要があるため、アプリケーションの「偽の」環境を作成し、使用可能なリソースをホストから分離したままにすることができます。環境、可能な限り。このため、「外部」OOM状態(オーバーコミット/ OOMキラー/その他が原因)の結果としてしばらくしてからではなく、起動時に失敗したり、とにかく自身の状態に干渉するような状態に苦しむことが望ましい場合があります内部OOM処理戦略(一般に、VMは必要なリソースを最初から取得し、ホストシステムは最後までそれらを「無視」する必要があります。これは、グラフィックスカードと共有される物理RAMの量が決してないことです。 -OSに触れた)。

Apacheについては、サーバー全体をときどき強制終了して再起動する方が、単一の子を単一の接続とともに(=子の接続)の最初から失敗させるよりも優れているとは思えません(まるで新しいインスタンスのように)別のインスタンスがしばらく実行された後に作成されたJVM)。最高の「解決策」は特定のコンテキストに依存する可能性があると思います。たとえば、eコマースサービスを考慮すると、進行中の注文の確定を中断するリスクがあるなど、サービス全体を失うのではなく、ショッピングチャートへのいくつかの接続がランダムに失敗することがあります。 (さらに悪い場合)支払いプロセス、ケースのすべての結果(無害かもしれませんが、有害かもしれません-そして確かに、問題が発生したとき、

同様に、ワークステーション上で最もリソースを消費するプロセスであるため、OOMキラーの最初の選択肢となるプロセスは、ビデオトランスコーダーやレンダリングソフトウェアなど、メモリを集中的に使用するアプリケーションになる可能性があります。ユーザーは手を触れたくない。この考慮事項は、OOMキラーのデフォルトポリシーが攻撃的すぎることを示唆しています。これは、いくつかのファイルシステムの方法に似た「最悪の適合」アプローチを使用します(OOMKは、可能な限り多くのメモリを解放し、キルされたサブプロセスの数を減らして、短時間でさらなる介入を防止します。 fsは、特定のファイルに実際に必要なディスクスペースよりも多くのディスクスペースを割り当てることができます。これにより、ファイルが大きくなった場合のさらなる割り当てを防ぎ、ある程度断片化を防ぎます。

ただし、「ベストフィット」アプローチなどの反対のポリシーが望ましいと考えられるため、特定の時点で必要な正確なメモリを解放し、「大きな」プロセスに迷惑をかけないでください。メモリだけでなく、カーネルもそれを知ることができません(うーん、プロセスがそれ以上必要ないメモリを割り当てている場合、ページアクセスカウントと時間のトレースを保持するとヒントになると想像できます。メモリを浪費している、または大量に使用していますが、メモリの浪費メモリおよび CPUを集中的に使用するアプリケーションを区別するために、CPUサイクルでアクセス遅延を重み付けする必要がありますが、不正確である可能性がありますが、このようなヒューリスティックには過剰なオーバーヘッドがあります)。

さらに、可能な限り少ないプロセスを強制終了することは常に良い選択であるというのは真実ではないかもしれません。たとえば、デスクトップ環境(サンプルとしてネットトップやリソースが限られているネットブックを考えてみましょう)では、ユーザーが複数のタブでブラウザーを実行している可能性があります(したがって、メモリを消費します-これがOOMKの最初の選択肢だと仮定しましょう) 、その他のアプリケーション(保存されていないデータを含むワードプロセッサ、メールクライアント、pdfリーダー、メディアプレーヤーなど)、いくつかの(システム)デーモン、およびいくつかのファイルマネージャーインスタンス。現在、OOMエラーが発生し、OOMKは、ユーザーがネット上で「重要」とみなされる何かをしているときにブラウザーを強制終了します...ユーザーは失望します。一方、いくつかのファイルマネージャーを閉じる」

とにかく、ユーザーは何をすべきかを自分で決定できるようにする必要があると思います。デスクトップ(=インタラクティブ)システムでは、ユーザーにアプリケーションを閉じるように要求するリソースが予約されている(ただし、いくつかのタブを閉じるだけでも十分な場合があります)ために比較的簡単に実行でき、選択を処理できます十分なスペースがある場合は、追加のスワップファイルを作成します)。サービス(および一般)については、さらに2つの可能な拡張機能も検討します:1つはOOMキラーインターベンションのロギング、および障害を簡単にデバッグできる方法での障害の開始/分岐プロセス(たとえば、新しいプロセスの作成または分岐を発行するプロセスに通知します。したがって、適切なパッチが適用されたApacheのようなサーバーは、特定のエラーに対してより良いロギングを提供できます。これは、オーバーコミット/ OOMKが努力していることとは無関係に行うことができます。2番目に、しかし重要ではないが、OOMKアルゴリズムを微調整するメカニズムを確立することができます-プロセスごとに特定のポリシーをプロセスごとに定義することはある程度可能であることはわかっていますが、関連するプロセスを識別し、それらにある程度の重要性を与えるために、アプリケーション名(またはID)の1つ以上のリストに基づく「集中型」構成メカニズム(リストされた属性に従って)。また、トップレベルのユーザー定義リスト、システム(配布)定義リスト、および(ボトムレベル)アプリケーション定義エントリ(つまり、 、たとえば、DEファイルマネージャーはOOMKに任意のインスタンスを安全に強制終了するように指示できますが、

Morover、APIを提供して、アプリケーションが実行時に「重要度」レベルを上げたり下げたりできるようにすることができます(メモリ管理の目的と実行優先度に関係なく)。たとえば、Wordプロセッサは「重要度」は低いが、ファイルにフラッシュする前、または書き込み操作が実行される前に一部のデータが保持されているため上昇し、そのような操作が終了すると再び重要度が低くなります(同様に、ファイルマネージャーは、個別のプロセスを使用する代わりに、データとその逆を処理するためにファイルを点灯します。Apacheは、異なる子に異なるレベルの重要性を与えるか、sysadminsによって決定されApacheまたは他の種類のサーバーを通じて公開されるポリシーに従って子の状態を変更できます- 設定)。もちろん、このようなAPIは悪用/誤用される可能性がありますが、カーネルはシステムで何が起こっているのか(およびメモリ消費/作成時間など)に関連する情報なしにメモリを解放するためにプロセスを任意に強制終了するのに比べて、小さな懸念だと思います「十分に関連していない、または「検証中」)-ユーザー、管理者、およびプログラム作成者のみが、何らかの理由でプロセスが「まだ必要」であるかどうか、その理由、および/またはアプリケーションが状態をリードしているかどうかを本当に判断できます死亡した場合のデータ損失またはその他の損害/トラブル。ただし、たとえば、プロセスによって取得された特定の種類のリソース(ファイル記述子、ネットワークソケットなど)を探し、保留中の操作でプロセスがより高い「状態」にあるべきかどうかを判断できるなど、いくつかの仮定を立てることができます1セット、

または、オーバーコミットを避けて、カーネルに必要なことだけをカーネルに任せ、リソースを割り当てます(ただし、OOMキラーのように任意にリソースを救出しません)、プロセスをスケジュールし、飢andとデッドロックを防止します(またはそれらから救出します)。メモリ空間の分離など...

また、オーバーコミットアプローチについてもう少し説明します。他の議論から、オーバーコミットに関する主な懸念の1つは(それを望む理由と考えられるトラブルの原因の両方として)フォークの処理であると考えました:正直なところ、私はコピーがどのくらい正確かわかりません書き込み戦略が実装されていますが、積極的な(または楽観的な)ポリシーは、スワップに似たローカリティ戦略によって緩和される可能性があると思います。つまり、フォークされたプロセスコードページとスケジューリング構造を複製(および調整)する代わりに、実際の書き込みの前に他のいくつかのデータページをコピーし、親プロセスがより頻繁に書き込むためにアクセスしたページ(つまり、書き込み操作にカウンターを使用します)。

もちろん、私見のすべて。


5
「さらに、アプリケーションが実行時に「重要度」レベルを上げ下げできるようにするために、APIを提供できます」重要度は/proc/$PID/oom_adjです。
Vi。

1
JVMに関しては、場合によってはメモリのオーバーコミットが必要になるという落とし穴があります。元のJVMから別のJVMを作成する場合、fork()を呼び出します。fork呼び出しは、実際にプロセスを開始するまで、元のプロセス(最初)と同じだけのメモリを割り当てます。だから、あなたは4ギガバイトJVM持っていて、オーバーコミットを持っていない限り、あなたがそれを行うために、メモリ8GBのが必要になります、それから、新しい512キロバイトJVMを作成したいと言う...
ALCI

4
@Vi。今のようです/proc/$PID/oom_score_adj
-m3nda

1

システムの安定性を脅かす可能性のある程度までメモリがプロセスによって徹底的に使い果たされると、OOMキラーが見えてきます。OOM Killerのタスクは、残りのプロセスがスムーズに機能するために十分なメモリが解放されるまでプロセスを強制終了することです。OOM Killerは、殺すために「最適な」プロセスを選択する必要があります。ここでの「最良」とは、強制終了時に最大メモリを解放するプロセスを指し、システムにとっては最も重要ではありません。第一の目標は、行われる損傷を最小限に抑えると同時に、解放されるメモリの量を最大限にするプロセスの最小数を殺すことです。これを容易にするために、カーネルは各プロセスのoom_scoreを維持します。pidディレクトリの下の/ procファイルシステムにある各プロセスのoom_scoreを確認できます。

# cat /proc/10292/oom_score

プロセスのoom_scoreの値が高いほど、メモリ不足の状況でOOM Killerによって強制終了される可能性が高くなります。

クレジット:-LinuxカーネルがOOMキラーを開始しています

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.