...

ホスティング運用における「OOM Score」と「OOM Score Adjust」の解説

私が説明するのは、 OOMスコア また、ホスティング運用における具体的な制御手段として「OOM Score Adjust」があります。これにより、メモリ不足時にLinuxのOOMキラーがどのプロセスを終了させ、どのプロセスを保護するかを指定できます。これにより、次のような状況でも制御を維持できます。 RAM 不足し始めたら、重要なサービスがオンラインで維持されるよう確保してください。.

中心点

概要を素早く把握できるよう、主な考えを簡潔にまとめます。.

  • 優先順位 リソース不足の場合:OOMスコアに基づいて、どのプロセスを最初に終了させるべきかを判断します。.
  • 微調整 oom_score_adj を使用する場合:-1000(防御)から +1000(犠牲)まで。.
  • ダイナミクス 固定値ではなく:評価値は負荷や構成に応じて変化します。.
  • ホスティング練習: 重要なサービスは保護し、重要でないワーカーは終了させる。.
  • 原因 解決方法:リミット、Cgroups、およびRAMの割り当て設定を確認する。.

LinuxのOOMキラーの仕組み

高い場合 ストレージの圧力 Linuxカーネルは、システムの応答性を維持するために、どのプロセスを終了させるかを決定します。その際、私は カーネル 各プロセスに、現在のメモリ使用量に大きく依存する一種の「悪さ」のスコアを割り当てます。十分な量のRAMやスワップ領域が確保できない場合、OOMキラーが作動し、スコアが最も高いプロセスを終了させます。 このメカニズムはシステムの停止を防ぐものですが、ホストおよびサービスレベルでの適切な容量計画に代わるものではありません。私はOOMログを分析し、そのサービスがメモリ不足によるものなのか、設定ミスによるものなのかを判断します。.

OOMスコアの理解:ダイナミクスとスケール

をチェックする。 OOMスコア プロセスの /proc/PID/oom_score に記録された値を読み取り、そのプロセスが現在どれほど危険な状態にあるかを把握します。 スケールは実質的に0から1000の範囲です。1000に近いほど、そのプロセスはキラーによって終了される可能性が高くなります。この値は、負荷のピーク、Cgroupのリミット、キャッシュサイズが絶えず変化しているため、あくまでその時点でのスナップショットに過ぎません。 そのため、私はこのスコアを単独で評価することは決してなく、メモリ、スワップ、オーバーコミット、および並行実行中のプロセスといった文脈の中で評価しています。このスコアを定期的に確認することで、典型的なパターンを把握し、サービスが停止してしまう前にボトルネックを予測することができます。.

OOMスコア調整を的確に活用する

と一緒に oom_score_adj プロセスの評価値を-1000から+1000の範囲で積極的に調整します。-1000に設定するとプロセスを完全に保護し、一方、高い正の値を設定すると、意図的にそのプロセスを犠牲にする準備が整います。 保護するプロセスの数は控えめに設定しています。保護されるプロセスが多すぎると、OOMキラーの動作の余地が狭まってしまうからです。 低い値を割り当てる典型的な候補としては、SSH、モニタリング、リバースプロキシのフロントエンド、および機密性の高いデータベースコントローラが挙げられます。バックグラウンドジョブ、レポーター、あるいは短命なワーカーには、リソースが逼迫した際にもユーザーインターフェースが引き続き応答するように、より高い値を割り当てる傾向があります。.

ホスティングにおける優先順位の設定

生産性の高い環境では、私は明確な 優先順位 フロントエンド、API、データベース、バッチ処理の間で。まず、ユーザー視点から見て稼働し続ける必要があるサービスを特定し、それらに適切なOOM調整値を設定します。systemdでは、サービスユニットファイルにOOMScoreAdjust=を設定し、各値の目的を文書化します。 もともとsystemdでサービスを管理している場合は、運用プロセスを効率化できます。そのための入門として、以下のリソースが参考になります。 ホスティングにおけるsystemd. このようにして、障害を偶然に任せるのではなく、事前に予防策を講じ、ユーザー体験を確実にオンライン上で維持しています。.

Cgroups、コンテナ、および制限

私は決して忘れません、その cgroups, というのも、コンテナやサービスはそれぞれ独自のリソース環境の中で動作しているからです。OOMスコアが中程度のプロセスであっても、そのcgroupのメモリ制限が厳しく、一時的にその制限を超えてしまうと、プロセスは終了してしまう可能性があります。そのため、私はcgroup v2の制限値を確認し、負荷プロファイルに合わせてハードリミットとソフトリミットを適切に調整しています。 マルチテナントや共有ホスティングを運用している場合は、適切に設定されたクォータとアカウンティングが役立ちます。詳細については、以下をご覧ください。 ホスティングにおけるcgroup v2. 連携がうまくいっていれば、OOMの調整とリミットは、絶妙に調和した2つの調整ネジのように機能する。.

OOMイベント時の診断と監視

ドカンと音がした時は、はっきりとした 信号 および分析の再現性。dmesg、journald、および /var/log/kern.log を解析し、OOM 関連の行を保存した上で、対象プロセスの PID と oom_score、oom_score_adj を取得します。 定期的なチェックには、メモリを最も多く消費しているプロセスを一覧表示し、警告閾値に達した際にアラートを発するスクリプトを使用しています。より詳細に調査したい方は、以下の記事に体系的なアプローチが記載されています。 OOMキラーの分析. 恒常的な環境では、RSS、キャッシュ、スワップイン/アウト、コンテナの制限といったメトリクスを監視に組み込み、傾向をいち早く把握できるようにしています。.

管理者向け表形式のチートシート

以下の概要は、私が簡潔な ガイド, 、役割の優先順位を付け、調整内容を記録する際です。「理由」の列には、なぜその役職に「保護」や「犠牲の覚悟」が割り当てられるのかが示されています。 数値はプロジェクトに合わせて調整していますが、この指針があることで迅速な意思決定が可能になります。この表を出発点として活用すれば、事後分析や変更依頼の際にも明確な判断が下せます。重要なのは、システム全体に常に余裕を持たせ、強制的な削除(ハードキル)が必要になるケースを極力減らすことです。.

コンポーネント 典型的な目的地 例:oom_score_adj 理由
SSH-デーモン シューツェン -500 ~ -900 手狭な場所でも、処置のためのアクセスを確保する。.
リバースプロキシ(nginx/HAProxy) シューツェン -300 ~ -700 インバウンドトラフィックに対応し、エラーページを表示する。.
データベース-コントローラー/プライマリインスタンス シューツェン -200 ~ -600 接続を維持し、データへのアクセスを確保する。.
PHP-FPM/アプリケーション・ワーカー 中立から犠牲を厭わないまで 0 ~ +300 多数の並列ワーカーが停止する可能性があります。.
バッチ/バックアップ/レポート 犠牲を払う覚悟がある +300 ~ +800 ユーザーへの影響なしに延期可能。.
インデクサー/キューコンシューマー 犠牲を払う覚悟がある +200 ~ +600 一時停止可能で、後で追いつくことができます。.

WordPressとPHPのワーカーを適切に制限する

WordPressでは、次の点に注意しています 労働者-プロセス数、memory_limit、および画像処理やインポートといった大規模な処理。私はPHP-FPMを、アクティブなプロセス数がRAM容量に見合うように設定し、プロセスが雪だるま式に増えないようにしています。データベースに関しては、バッファとキャッシュのサイズを合計し、スパイクが発生してもシステムが完全にブロックされないよう、余裕を持たせています。 OpCache、オブジェクトキャッシュ、画像最適化機能はメモリ使用量を急速に増加させるため、これらを注意深く監視しています。これにより、一時的な負荷のピークによって重要なフロントエンドプロセスが直ちに停止してしまうことを防いでいます。.

実践:ポリシーとプレイブック

私は ポリシー 簡潔かつ実行可能なものにしておくことで、緊急時にチームが躊躇することなく対応できるようになります。これには、保護対象を定義し、犠牲となるロールを指定し、systemdユニットに OOMScoreAdjust= を設定し、その値をリポジトリに文書化することが含まれます。 ツールとテスト負荷を用いて、犠牲となるシステムの優先順位が目標に合致するまで効果を検証します。その後、ログ、アラート、初期対応を記述したプレイブックを作成します。これにより、新しいメンバーが引き継いだ場合でも、対応の一貫性が保たれます。.

# systemd-Unit のサンプルコード
[Service]
OOMScoreAdjust=-400
# 再読み込みと再起動:
# systemctl daemon-reload && systemctl restart nginx

# 実行中の確認:
cat /proc/$(nginxのPID)/oom_score
cat /proc/$(nginxのPID)/oom_score_adj

# 一時的な値の引き上げ/引き下げ(root):
echo 300 | sudo tee /proc//oom_score_adj

よくある間違いと対策

多くの問題は、次のような理由から生じます。 限界 整合性が取れていない:PHPワーカーが多すぎ、DBキャッシュが大きすぎ、スパイク負荷に対応する余地がない。その結果、わずかな調整で済むはずなのに、OOMキラーが頻繁に作動してしまう。 私はまずワーカー数を調整し、その効果を測定した上で、必要性が明確に示された場合にのみRAMを増設します。また、多くのプロセスを-1000に設定することも逆効果です。カーネルには動作の自由度が必要だからです。私は、緊急時にもシステムが秩序を持って対応できるよう、適切な判断に基づいて優先順位を設定しています。.

オーバーコミット、スワップ、およびメモリ使用率

私は自分の オーバーコミット戦略 この設定は、システムがOOMゾーンに陥る速度を決定するため、慎重に設定する必要があります。vm.overcommit_memory=0(ヒューリスティック)に設定すると、カーネルが使用状況や履歴に基づいてコミット上限を推定するため、多くの場合安定して動作します。 vm.overcommit_memory=2 に vm.overcommit_ratio を組み合わせると、許容される仮想メモリ使用量の最大値が定義されるため、設定はより厳格になります。 vm.overcommit_memory=1を一律に設定すると、メモリの予約は成功しても、後の割り当て時に深刻なエラーが発生するリスクがあります。これは、高負荷下でのOOMイベントのよくある原因となります。.

私はキャリブレーションを行います。 スワップ バッファを確保しつつ、レイテンシのボトルネックにならないように設定します。適度な vm.swappiness 値に設定することで、頻繁にアクセスされるパスにはメモリを割り当てたまま、使用頻度の低いページはスワップに回すことができます。 I/Oが遅い場合は、zswapやzramを弾力的なバッファとして活用できます。これによりOOMのリスクは低減されますが、CPUリソースを消費します。また、メモリ使用量の閾値も重要です。カーネルが適時にメモリを回収できるよう、vm.min_free_kbytesは十分に高い値に設定する必要があります。 この値を過小に設定しすぎると、システムは慌ただしいリクレイム処理に追い込まれ、最終的にOOMにつながるパドルジックを引き起こしてしまいます。.

# の例:保守的なオーバーコミットと適度なスワッピング
sysctl -w vm.overcommit_memory=2
sysctl -w vm.overcommit_ratio=90
sysctl -w vm.swappiness=30
# テスト用に /etc/sysctl.d/ に永続的に登録する

OOMScoreAdjust 以外の systemd オプション

OOMScoreAdjustに加え、systemdを使って 蓄熱式ガードレール サービスに直接設定します。MemoryMax= では厳格に制限(cgroup memory.max)し、MemoryHigh= は負荷時に緩やかに抑制し、MemorySwapMax= はスワップを抑制します。MemoryLow= と MemoryMin= は、負荷がかかった際にサービスのキャッシュ領域を優先的に確保し、重要なプロセスのパフォーマンス低下を遅らせます。 OOMPolicy=と組み合わせて、OOM発生時にsystemdがユニットレベルでどのような処理を行うかを制御します(例:サービスのみを停止するか、依存関係全体を終了させるか)。 スライスでは、Webフロントエンド、バッチ、DBといった役割をグループ化し、個々の異常値がシステム全体の安定性を損なわないよう、統一されたルールを導き出しています。.

保護は決して絶対的なものではないことに留意しています。たとえ-1000という値を持つプロセスであっても、絶望的な状況では退かなければならない場合があります。そのため、私は寛大でありながらも現実的な ミニマ (MemoryLow/Min) はごく一部のコアサービスにのみ適用し、すべての割り当ての合計が物理的に利用可能なメモリ容量を下回るかどうかを確認します。これにより、善意による保護措置がOOMキラーの正常な動作を妨げるのを防ぎます。.

Kubernetesとコンテナオーケストレーション

Kubernetes のようなオーケストレーション環境では、OOM ロジックは複数のレベルで機能します。私は リクエスト そして 限界 これにより、ポッドは希望するQoSクラスに分類されます。「Guaranteed」が最も強力な保護を提供し、「Burstable」は負荷を緩和し、「BestEffort」は最も影響を受けやすくなります。 kubeletは、その結果として算出されたOOMScoreAdjust値を自動的に割り当てます。したがって、私はコンテナ内での手動によるチューニング値ではなく、リソース指定に基づいて計画を立てています。 コンテナが memory.limit に達すると、ホストに空きメモリが残っていても、その cgroup 内でコンテナは終了します。これは従来のホスト OOM ではなく、制限値を守るための意図的な自己防衛措置です。.

私は次のことを考慮に入れている。 ネイティブメモリの割合 ヒープ構成(JVM/ノードなど)の範囲外で設定し、コンテナが予期せずリミットに達してクラッシュするのを防ぎます。さらに、ピーク時の負荷に備えてポッドのバッファを確保し、エヴィクションが発生しにくくなるよう、ノードのオーバーコミットは適度な範囲に抑えています。 cgroup v2が有効な場合は、memory.oom.groupを意図的に使用し、緊急時には個々のワーカーをゾンビPodに残すのではなく、プロセスグループ全体が秩序立てて停止するようにしています。これにより、システムをクリーンな状態に保ち、リカバリも予測可能になります。.

診断の精緻さ:SMaps、PSI、および再現性のある検査

詳細な分析を行う際には、私は /proc- 状況把握と負荷メトリクス。/proc/PID/status は VmRSS、VmSwap、スレッド数を表示します。/proc/PID/smaps_rollup は、Anon、File、Shmem などの割合をまとめて表示してくれるため、細かい部分に惑わされることなく把握できます。 これにより、ページキャッシュが誤った情報を示しているのか、それとも匿名ページ(実際の作業データセット)が増加しているのかを判断できます。/proc/pressure/memory を使用して、 生販在-シグナル、つまりシステムがアクティブなリクレイムやストールにどれだけの時間を費やしているか。私は、OOMが発生するずっと前にこれらの値についてアラートを発信しています。これは、自動的な対策(スロットリング、スケーリング、ワーカー数の削減)をトリガーするのに最適です。.

# 関連するスナップショット
journalctl -k -g "Out of memory|oom-killer"
cat /proc/pressure/memory
grep -E "VmRSS|VmSwap|Threads" /proc//status
cat /proc//smaps_rollup

# OOM の再現(テスト環境!)
stress-ng --vm 2 --vm-bytes 80% --timeout 30s

特殊なケース:コンテナ内のJVM、Node.js、PHP

JVM-サービスには注意が必要だ。なぜなら、ヒープだけでなく、メタスペース、スレッドスタック、ダイレクトバッファ、そしてネイティブアロケータの挙動も考慮しなければならないからだ。 私はMaxRAMPercentageを用いてコンテナに優しい制御を行い、これらの要素に余裕を持たせたヒープを設定しています。並列度が高い場合は、多数の小さなスタックが累積して深刻な問題となるため、スレッドプールを制限しています。 Node.js ハードキルを防ぐため、`-max-old-space-size` をコンテナの制限に合わせて調整します。そして、 ピーエッチピーエフピーエム pm.max_children は、RAM、リクエストあたりの平均使用量、memory_limit を基に計算し、さらにキャッシュやウェブサーバー用の予備容量を加味しています。こうすることで、ピーク時に初めて顕在化するような、徐々に進行する「雪崩」を未然に防いでいます。.

を保管している。 アロケーター戦略 注目点:多くのアリーナを持つglibcは、スレッド数の多いワークロードにおいてメモリの断片化を引き起こし、メモリ使用量を増加させる可能性がある。 特定のサービスについては、jemalloc や tcmalloc の方がより一貫したピーク値を示します。私はこれを重点的にテストし、その効果を記録した上で、慎重に導入を進めています。また、アップロードや一時ファイルが気づかれないうちに RAM を食い尽くすのを防ぐため、コンテナ内の tmpfs ディレクトリの容量を制限しています。.

Tmpfs、Huge Pages、およびページキャッシュ

tmpfs 見過ごされがちですが、サイズ制限がないとRAMの一定割合まで肥大化し、他の場所で突然空き容量が不足してしまいます。特にビルドやアップロード用のパスでは、意図的に size= を指定してtmpfsをマウントするようにしています。. 透明な巨大ページ(THP) 断片化とレイテンシに影響を与えます。レイテンシが重要なサービスでは、適切な割り当てのみが恩恵を受けるよう、しばしば「madvise」を設定しています。KSMは重複排除を行いメモリを節約できますが、CPUリソースを消費します。開発用ホストでは有用ですが、パフォーマンスが重要な環境では、その効果とオーバーヘッドを検証しています。.

ページキャッシュ これは「無駄な」メモリではなく、I/Oを高速化するものです。これを過度に強制的に追い出したり、ドロップキャッシュを恒久的な対策として使用したりすると、そのコストがレイテンシの急増という形で現れてしまいます。 むしろ、ロールごとにメモリ目標を定義し、cgroupメカニズム(memory.high / memory.max)を通じて公平な配分を強制する方が望ましい。そうすることで、重要なサービスのホットセットはRAMに残り、OOM(メモリ不足)の状況も減少する。.

日常生活のまとめ

私は OOMスコア これを危険度の指標として用い、oom_score_adj を使って犠牲にする対象の適切な優先順位を調整します。ユーザーに影響を与えるサービスは保護し、延期可能なジョブは犠牲の対象とし、すべての値を追跡可能な形で記録します。 Cgroupのリミット、ワーカー数、キャッシュサイズは、スパイクが広範囲に波及しないよう、一体として計画します。 ログ、モニタリング、そして簡潔なプレイブックを活用することで、OOMイベントを迅速に検知し、的確に解決できるようにしています。この徹底した管理により、ホストの信頼性を維持し、本番環境での夜間に予期せぬトラブルが発生するのを防いでいます。.

現在の記事