LinuxのOOMキラーは、さまざまなアプリケーションで頻繁に大混乱を引き起こし、カーネル開発側では、これを改善するためにそれほど多くのことは行われていないようです。新しいserverを設定するときのベストプラクティスとして、メモリオーバーコミットのデフォルトを逆にすること、つまり、あなたが知らない限り、オフにすること(vm.overcommit_memory=2
)は、より良いことではありませんか?あなたの特定の用途のためにそれをしたいですか?そして、それらのユースケースは、あなたがあなたがオーバーコミットを望んでいることを知っているところでしょうか?
おまけとして、vm.overcommit_memory=2
の場合の動作はvm.overcommit_ratio
とスワップ領域に依存するため、この2つのセットアップ全体が適切に機能し続けるように、後者2つをサイジングするための良い経験則は何でしょうか。
興味深いアナロジー( http://lwn.net/Articles/104179/ から):
航空機会社は、機内で燃料を少なくして飛行機を飛ばす方が安かったことを発見しました。飛行機はより軽くなり、燃料使用量が減り、お金が節約されました。しかし、まれに燃料の量が不足して飛行機が墜落することがありました。この問題は、特殊なOOF(燃料不足)メカニズム)を開発することにより、会社のエンジニアによって解決されました。緊急の場合、乗客が選択され、飛行機から投げ出されました(必要に応じて手順が繰り返されました。)大量の理論が作成され、多くの出版物が排出される犠牲者を適切に選択する問題に専念しました。犠牲者は無作為に選ばれるべきですか、それとも最も重い人を選ぶべきですか?または最年長ですか?乗客が追い出されないように料金を支払って、被害者が乗るときに最も貧しい人になりますか?たとえば、最も重い人が選ばれた場合、パイロットだった場合に特別な例外がありますか?乗客は免除されますか?OOFメカニズムが存在したので、それは時々アクティブになり、燃料不足がなくても乗客を排出します。エンジニアはこの誤動作がどのようにしているかを正確に研究しています引き起こした。
OOMキラーは、システムに過負荷をかけた場合にのみ大混乱を引き起こします。十分なスワップを与え、突然大量のRAMを消費することを決定するアプリケーションを実行しないでください。問題は発生しません。
具体的に質問に答えるには:
brk
(2)(およびmalloc
(3)などのラッパーを使用するラッパー)を適切に処理するように記述されているアプリケーションはほとんどありません。以前の仕事でこれを実験したところ、OOMの結果を処理するだけの場合よりも、メモリ不足エラーを処理できるすべてのものを取得するのは面倒だと思われました(この場合、 OOMが発生した場合に時々サービスを再起動する必要があるよりもはるかに悪かった-GFSは大量の糞便であるため、クラスター全体を再起動する必要があった)。基本的に、私の経験では、オーバーコミットをオフにするのは、理論的に聞こえるように実際にうまく機能することはめったにない素晴らしい実験です。これは、カーネル内の他の調整パラメータに関する私の経験とうまく対応しています。Linuxカーネルの開発者は、ほとんどの場合、あなたより賢く、デフォルトは、大多数のvastの場合に最適です。それらをそのままにして、代わりにどのプロセスにリークがあるかを見つけて修正します。
うーん、私はオーバーコミットとOOMキラーを支持する議論に完全に納得していません...ウォンブルが書いたとき、
「OOMキラーは、システムに過負荷がかかった場合にのみ大惨事を引き起こします。十分なスワップを与え、大量のRAMを突然使用することを決定するアプリケーションを実行しないでください。問題は発生しません。」
彼は、オーバーコミットとOOMキラーが強制されない、または「実際に」動作しない環境シナリオについて説明しています(すべてのアプリケーションが必要に応じてメモリを割り当て、割り当てられる十分な仮想メモリがある場合、メモリの書き込みは、エラーなので、オーバーコミット戦略が有効になっていても、オーバーコミットされたシステムについて実際に話すことはできませんでした)。それは、オーバーコミットとOOMキラーが介入を必要としない場合に最も効果的に機能する暗黙の承認に関するものです。これは、私が知る限り(そして私は多くを伝えることはできないと認めますが)、この戦略のほとんどの支持者によって何らかの形で共有されています。 Morover、メモリを事前に割り当てるときに特定の動作を持つアプリケーションを参照すると、ヒューリスティックに基づくデフォルトのシステムごとのアプローチではなく、特定の処理を配布レベルで調整できると思います(個人的に、ヒューリスティックはあまり良いアプローチではないと私は思いますカーネル関連)
JVMに関しては、まあ、それは仮想マシンであり、ある程度、起動時にすべてのリソースを割り当てる必要があります必要アプリケーションの「偽の」環境を作成し、利用可能なリソースは、可能な限りホスト環境から分離されています。したがって、「外部」のOOM状態(オーバーコミット/ OOMキラー/その他が原因)の結果として、しばらくしてからではなく、起動時に失敗するか、とにかくそのような状態が自身の状態に干渉することで苦しむことが望ましい場合があります。内部OOM処理戦略(一般に、a VMは必要なリソースを最初から取得し、ホストシステムはそれらを最後まで無視する必要があります。同じ方法で、グラフィックスカードは、OSが触れることはありません。
Apacheについては、サーバー全体をときどき強制終了して再起動する方が、単一の子を単一の接続と一緒に、その(=子/接続)の最初から(まるでまったく新しいインスタンスであるかのように)失敗させるよりも良いとは思えません別のインスタンスがしばらく実行された後に作成されたJVM)。最善の「解決策」は、特定のコンテキストに依存すると思います。たとえば、eコマースサービスを考えると、サービス全体を失うのではなく、ショッピングチャートへのいくつかの接続がランダムに失敗することがはるかに望ましい場合があります。たとえば、進行中の注文の確定を中断するリスクがあります。 (多分悪い)支払いプロセス、およびケースのすべての結果(多分無害、しかし多分無害-そして確かに、問題が発生した場合、これらはデバッグ目的の再現不可能なエラー状態よりも悪い)。
同じように、ワークステーションでは、最も多くのリソースを消費するプロセスであり、OOMキラーの最初の選択肢となるようなテーリングは、ビデオトランスコーダーやレンダリングソフトウェアなど、メモリを集中的に使用するアプリケーションであり、おそらく唯一のアプリケーションです。ユーザーは手を触れられたくない。この考慮事項は、OOMキラーのデフォルトポリシーがあまりにも積極的であることを示唆しています。それは、いくつかのファイルシステムの方法と似た「最悪の適合」アプローチを使用します(OOMKは、可能な限り多くのメモリを解放しようとしますが、キルされたサブプロセスの数を減らし、短時間でのさらなる介入を防ぎます。また、fsは特定のファイルに実際に必要なディスクスペースをさらに割り当てることができるため、ファイルが大きくなった場合にそれ以上の割り当てが行われず、断片化がある程度防止されます)。
ただし、「ベストフィット」アプローチなどの反対のポリシーが望ましい場合があるため、特定の時点で必要な正確なメモリを解放し、無駄になっている可能性がある「大きな」プロセスに煩わされないようにするメモリもそうでないかもしれませんし、カーネルもそれを知ることができません(うーん、ページアクセスの数と時間の追跡を維持することで、プロセスがメモリを割り当てている場合にヒントが必要になる可能性があるため、プロセスがそれ以上必要かどうかを推測できます。はメモリを浪費している、または単に大量に使用しているが、メモリの浪費とメモリを区別するために、CPUサイクルでアクセス遅延を重み付けする必要があるand CPU集中型アプリケーション。過度のオーバーヘッド)。
さらに、可能な限り少ないプロセスを強制終了することが常に良い選択であるとは限りません。たとえば、デスクトップ環境(例として、リソースが限られているネットトップまたはネットブックについて考えてみましょう)で、ユーザーは複数のタブでブラウザーを実行している場合があります(したがって、メモリを消費します-これがOOMKの最初の選択肢であるとしましょう) 、およびその他のいくつかのアプリケーション(保存されていないデータを含むワードプロセッサ、メールクライアント、pdfリーダー、メディアプレーヤーなど)、およびいくつかの(システム)デーモン、およびいくつかのファイルマネージャーインスタンス。これで、OOMエラーが発生し、OOMKは、ユーザーがネット上で「重要」と見なされる何かを実行しているときにブラウザーを強制終了することを選択します...ユーザーは失望します。一方、アイドル状態にあるいくつかのファイルマネージャーのインスタンスを閉じると、システムを機能させるだけでなく、より信頼性の高い方法で機能させながら、必要なメモリの正確な量を解放できます。
とにかく、ユーザーは自分で何をすべきかを自分で決定できるようにする必要があると思います。デスクトップ(=インタラクティブ)システムでは、ユーザーにアプリケーションを閉じて(いくつかのタブを閉じるだけで十分です)、選択を処理するための十分なリソースが確保されている場合、比較的簡単に実行できます(オプションで十分なスペースがある場合は、追加のスワップファイルを作成します)。サービス(および一般的に)についても、考えられる2つの拡張機能を検討します。1つはOOMキラーインターベントのログ記録であり、エラーを簡単にデバッグできるようにプロセスの開始/フォークの失敗をログに記録することです(たとえば、API新しいプロセスの作成またはフォークを発行するプロセスに通知します-したがって、適切なパッチを適用したApacheなどのサーバーは、特定のエラーに対してより適切なロギングを提供できます。これは、overcommit/OOMKが機能していることとは無関係に実行できます。 2番目に重要ではありませんが、OOMKアルゴリズムを微調整するためのメカニズムを確立することができます。プロセスごとに特定のポリシーを定義することはある程度可能ですが、アプリケーション名(またはID)の1つ以上のリストに基づく「集中型」構成メカニズム。関連するプロセスを識別し、それらに特定の重要度を(リストされた属性に従って)与えます。このようなメカニズムは階層化する必要があります(または少なくとも可能性があります)。これにより、トップレベルのユーザー定義リスト、システム(配布)定義リスト、および(ボトムレベル)アプリケーション定義エントリ(したがってたとえば、DEファイルマネージャーはOOMKにインスタンスを安全に強制終了するように指示できます。ユーザーがインスタンスを安全に再オープンして、失われたファイルビューにアクセスできるためです。一方、データの移動/コピー/作成などの重要な操作は、より「特権的な」プロセス)。
Morover、APIを提供して、アプリケーションが実行時に(メモリ管理の目的および実行の優先度に関係なく)「重要度」レベルを上げたり下げたりできるようにすることができます。これにより、たとえば、ワードプロセッサを「重要度」は低いが、ファイルにフラッシュする前に一部のデータが保持されるか、書き込み操作が実行されているときに上昇し、そのような操作が終了すると重要性が再び低下します(同様に、ファイルマネージャーは、個別のプロセスを使用するのではなく、データを処理するためにファイルを照らし、その逆を行います。Apacheは、異なる子に異なるレベルの重要度を与えるか、sysadminsによって決定され、Apacheまたはその他の種類のサーバーを通じて公開されるいくつかのポリシーに従って子の状態を変更できます。 - 設定)。もちろん、そのようなAPIは悪用される可能性があり、悪用される可能性がありますが、システムで何が起こっているかに関する関連情報なしにプロセスを強制終了してメモリを解放するカーネル(およびメモリ消費/作成時間または同様に、私にとって十分な関連性や「検証」はありません)-ユーザー、管理者、プログラムライターのみが、プロセスが何らかの理由で「まだ必要」かどうか、理由は何か、および/またはアプリケーションが存在するかどうかを実際に判断できます殺された場合、データの損失やその他の損傷/トラブルにつながる状態。ただし、たとえば、プロセスによって取得された特定の種類のリソース(ファイル記述子、ネットワークソケットなど)を探して、保留中の操作を行うと、プロセスをより高い「状態」にする必要があるかどうかを判断できます。 1つのセット、またはその「自己確立」のセットが必要以上に高く、下げることができる場合(積極的なアプローチ、特定の状態を強制する、または上記のリストを通じて-尊重することを求めるなどのユーザーの選択によって置き換えられない限り)アプリケーションの選択)。
または、オーバーコミットを回避して、カーネルに必要なことだけを実行させ、リソースの割り当て(ただし、OOMキラーのようにそれらを任意に救出しない)、プロセスのスケジューリング、飢餓とデッドロックの防止(またはそれらからの救出)、完全なプリエンプションの確保とメモリ空間の分離など...
また、オーバーコミットアプローチについてもう少し説明します。他の議論から、私はオーバーコミットに関する主な懸念の1つが(それを望む理由と考えられるトラブルの原因の両方として)フォークの処理からなるという考えを作りました:正直なところ、コピーの正確さはわかりません- on-write戦略が実装されていますが、攻撃的な(または楽観的な)ポリシーは、スワップに似た局所性戦略によって軽減される可能性があると思います。つまり、フォークされたプロセスコードページとスケジューリング構造を単にクローン(および調整)する代わりに、実際の書き込みの前に他のいくつかのデータページをコピーして、親プロセスがより頻繁に(つまり、書き込み操作にカウンターを使用する)。
もちろん、すべてが私見です。
システムの安定性を脅かす可能性のある程度にプロセスがメモリを使い果たしている場合、OOMキラーが登場します。残りのプロセスが円滑に機能するために十分なメモリが解放されるまで、プロセスを強制終了するのはOOMキラーのタスクです。 OOMキラーは、殺すための「最良の」プロセスを選択する必要があります。ここで「最良」とは、強制終了時に最大メモリを解放するプロセスを指し、システムにとって最も重要ではありません。主な目的は、実行するダメージを最小限に抑え、同時に解放されるメモリの量を最大化する、最小限の数のプロセスを強制終了することです。これを容易にするために、カーネルは各プロセスのoom_scoreを維持します。 pidディレクトリの下の/ procファイルシステムで、各プロセスのoom_scoreを確認できます
# cat /proc/10292/oom_score
プロセスのoom_scoreの値が高いほど、メモリ不足の状況でOOMキラーによって強制終了される可能性が高くなります。
クレジット:- LinuxカーネルがOOMキラーを開始しています