「サーバが重い。ロードアベレージが10を超えている」という報告があったとき、あなたはどこを見るか。
「ロードアベレージが高い=CPUが重い」と思い込んで対処しようとすると、原因がI/O待ちだった場合に全く効かない対策を取ることになる。ロードアベレージの正体を正確に理解することで、ボトルネックの切り分けが速くなる。
ロードアベレージとは何か
ロードアベレージは「実行待ちのプロセス数の移動平均」だ。uptimeやtopで確認できる。
$ 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表示 | 意味 | ロードアベレージに加算 |
|---|---|---|---|
| Running | R | CPU実行中または実行待ちキューにいる | ✅ |
| Uninterruptible Sleep | D | I/O完了待ち | ✅ |
| Interruptible Sleep | S | イベント待ち(sleepコマンド等) | ❌ |
| Zombie | Z | 終了済みだが親が回収していない | ❌ |
ここが重要: 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部分) |
| b | I/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見直し・ネットワーク改善 |
まとめ
ロードアベレージが高いときの調査手順:
uptimeでロードアベレージを確認sar -uで %iowait vs %user を確認してCPU/I/Oを切り分けps aux | awk '$8=="D"'でI/O待ちプロセスを特定sar -rやfreeでメモリ状況を確認iostat -xでディスクI/Oの詳細を掘り下げ
「推測するな、計測せよ」——この本から学んだ最も重要な教えだ。