Linuxロードアベレージを正確に理解する——sar・vmstat・psで障害の原因を特定する

「ロードアベレージが高い=CPUが重い」は誤解。プロセスの状態遷移からロードアベレージの正体を理解し、sar・vmstat・psを使ってCPUとI/Oのボトルネックを正確に切り分ける方法を解説する。

「サーバが重い。ロードアベレージが10を超えている」という報告があったとき、あなたはどこを見るか。

「ロードアベレージが高い=CPUが重い」と思い込んで対処しようとすると、原因がI/O待ちだった場合に全く効かない対策を取ることになる。ロードアベレージの正体を正確に理解することで、ボトルネックの切り分けが速くなる。


ロードアベレージとは何か

ロードアベレージは「実行待ちのプロセス数の移動平均」だ。uptimetopで確認できる。

$ uptime
 12:34:56 up 10 days,  3:45,  2 users,  load average: 2.45, 1.89, 1.23
#                                                      1分   5分   15分

重要なポイント: ロードアベレージはCPU使用率ではない。「実行を待っているプロセスの数」だ。


プロセスの状態遷移

ロードアベレージを理解するにはプロセスの状態を知る必要がある。

             実行可能         実行中
               [R]  ←─────── CPU使用
                │    ──────→

                ↓ I/O待ち・sleep等
             待ち状態
               [D] ← I/O待ち(Uninterruptible Sleep)
               [S] ← interruptible sleep(シグナルで起床可能)
状態ps表示意味ロードアベレージに加算
RunningRCPU実行中または実行待ちキューにいる
Uninterruptible SleepDI/O完了待ち
Interruptible SleepSイベント待ち(sleepコマンド等)
ZombieZ終了済みだが親が回収していない

ここが重要: D状態(I/O待ち)のプロセスもロードアベレージにカウントされる。ディスクI/Oが詰まっているとき、CPUは暇でもロードアベレージが跳ね上がる。


CPU負荷とI/O負荷を切り分ける

ロードアベレージが高いとき、まずsarでCPUとI/Oを確認する。

# sarでCPU使用率とI/O待ち率を確認
$ sar -u 1 5
Linux 5.15.0  ...

12:35:01  CPU   %user  %system  %iowait  %idle
12:35:02  all    85.2      3.1      0.5   11.2 CPU負荷(%userが高い)
12:35:03  all     2.1      1.2     89.3    7.4 I/O負荷(%iowaitが高い)
  • %user + %system が高い → CPUボトルネック
  • %iowait が高い → I/Oボトルネック(ディスク・NFS等)

実際の調査フロー

# Step 1: ロードアベレージと基本情報を確認
$ uptime
load average: 8.23, 6.45, 4.12  # 高い

# Step 2: CPU vs I/O を切り分け
$ sar -u 1 3
%iowait: 87.3  # I/Oボトルネックと判断

# Step 3: どのプロセスがI/O待ちか確認
$ ps aux | awk '$8=="D"'  # D状態のプロセスを抽出
# または
$ top  # → Dの列でD状態プロセスを確認

# Step 4: I/Oの詳細を確認
$ sar -d 1 3          # ディスクデバイスごとのI/O
$ iostat -x 1 3       # より詳細なI/O統計

各ツールの使い方

ps — プロセス情報を取得

# CPU使用率順にソート
$ ps aux --sort=-%cpu | head -10

# メモリ使用量順にソート
$ ps aux --sort=-%mem | head -10

# D状態(I/O待ち)のプロセスだけ抽出
$ ps aux | awk 'NR==1 || $8=="D"'

# 出力の主要カラム
# VSZ: 仮想メモリサイズ(確保しているが使っていない領域を含む)
# RSS: 物理メモリ実使用量(実際にRAMを占有している量)
# STAT: プロセス状態(R/S/D/Z等)
# TIME: CPU使用時間の累計

sar — OSレベルの各種指標を時系列で取得

# CPU使用率(1秒間隔で5回)
$ sar -u 1 5

# ロードアベレージ
$ sar -q 1 5

# メモリ使用状況
$ sar -r 1 5
# kbmemused: 使用中の物理メモリ
# kbbuffers: バッファキャッシュ(ディスクI/Oのキャッシュ)
# kbcached: ページキャッシュ(ファイルの読み取りキャッシュ)

# スワップ発生状況(スワップが起きていれば危険信号)
$ sar -W 1 5
# pswpin/s が 0 以上 → スワップインが発生している = メモリ不足

vmstat — 仮想メモリ関連情報を確認

$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 512345  23456 789012    0    0     0     1  234  456 85  3 11  1  0
 0  5      0 511234  23456 789012    0    0  8901   234  567  890  2  1  2 95  0
カラム意味
r実行待ちプロセス数(ロードアベレージのCPU部分)
bI/O待ちプロセス数(ロードアベレージのI/O部分)
si/soスワップイン/アウト(0以外はメモリ不足)
wa(cpu列)I/O待ち率

ページキャッシュとメモリ

Linuxは空きメモリをディスクI/Oのキャッシュ(ページキャッシュ)に積極的に使う。

$ free -h
              total        used        free      shared  buff/cache   available
Mem:           16Gi        4.2Gi       1.1Gi       234Mi        10Gi        11Gi

freeが少なくてもavailableが大きければメモリは足りている。ページキャッシュは必要になれば即座に解放される。

「メモリが1GBしかない!」と焦る前にavailableを確認する。


ボトルネックの種類と対処

ボトルネック症状対処
CPUバウンド%user高、ロードアベレージ高CPU追加・スケールアウト・処理の最適化
I/Oバウンド%iowait高、b列が多いSSD化・クエリ最適化・キャッシュ強化
メモリ不足スワップ発生(si/so > 0)メモリ増設・不要プロセス削減
ネットワーク%iowait高(NFSの場合)NFS見直し・ネットワーク改善

まとめ

ロードアベレージが高いときの調査手順:

  1. uptime でロードアベレージを確認
  2. sar -u で %iowait vs %user を確認してCPU/I/Oを切り分け
  3. ps aux | awk '$8=="D"' でI/O待ちプロセスを特定
  4. sar -rfree でメモリ状況を確認
  5. iostat -x でディスクI/Oの詳細を掘り下げ

「推測するな、計測せよ」——この本から学んだ最も重要な教えだ。