load averageが高い時の診断 - CPU待ち・I/O待ちの見極め

load averageが高い時の診断 - CPU待ち・I/O待ちの見極め

この記事で解決できること

  • load average が高いとき、CPU 待ちか I/O 待ちか を切り分けられる
  • Linux 特有の load average の定義(I/O 待ちも数える)を理解できる
  • uptime / top / vmstat / iostatどこを見れば判定できるか が分かる

結論(最短の切り分け)

  1. uptime で load average、nproc で CPU コア数を確認し、load > コア数 なら過負荷
  2. vmstat 1r 列(実行待ち)が多ければ CPU 飽和b 列(停止)と wa が多ければ I/O 待ち
  3. 方向が決まったら CPU 側は top/ps、I/O 側は iostat -x で犯人を特定

前提(対象環境)

  • OS:Ubuntu / 一般的な Linux
  • シェル:bash
  • ツール:vmstat / iostat / mpstatsysstat パッケージに含まれる(未導入なら sudo apt install sysstat

load average とは何か?数字の意味は?

結論: load average は「実行中+実行待ち+I/O 待ちのプロセス数」の指数移動平均で、uptime が表示する 3 つの値は左から 1 分・5 分・15 分平均。

uptime または cat /proc/loadavg で確認する。

$ uptime
 14:23:05  up 10 days,  3:42,  2 users,  load average: 4.85, 3.12, 1.90
$ cat /proc/loadavg
4.85 3.12 1.90 5/812 23145

3 つの数字は 左から 1 分・5 分・15 分 の平均。並びを比較すると傾向が読める。

  • 1 分 > 15 分(例:4.85 / 1.90)→ 負荷は 上昇中
  • 1 分 < 15 分 → 負荷は 収束中
  • 3 つが近い → 負荷が 定常的に高い

/proc/loadavg の 4 列目 5/812 は「実行中プロセス数 / 全プロセス数」、5 列目は最後に生成された PID。

load average はいくつから「高い」のか?

結論: 絶対値で判断せず CPU コア数と比較する。load average ÷ コア数 が 1.0 を超えると、処理を捌ききれずプロセスが待たされている状態。

load average は「待っているプロセスの数」なので、CPU コア数が多いほど許容値も上がる

$ nproc
4
  • コア数 4 で load average 4.0 → ほぼ 使い切り(待ち行列ゼロに近い)
  • コア数 4 で load average 8.0 → 2 倍の過負荷(半分のプロセスが順番待ち)

目安として load ÷ コア数 を使う。

load ÷ コア数 状態
~0.7 余裕あり
0.7~1.0 使い切りに近い(要注意)
1.0 超 過負荷(待ちが発生)

これは CPU 飽和の場合の目安。Linux では I/O 待ちも load に乗るため、コア数を超えていても「CPU はヒマ」というケースがある。次節がその切り分け。

なぜ Linux の load average は CPU 使用率と一致しないのか?

結論: Linux の load average は実行可能プロセス(TASK_RUNNING)に加え、割り込み不可の I/O 待ち(TASK_UNINTERRUPTIBLE / D 状態)も数える。だから CPU 使用率が低くても load average は跳ね上がる。

多くの UNIX が「CPU の実行キュー長」だけを load にするのに対し、Linux は割り込み不可スリープ(uninterruptible sleep、psD 状態)のプロセスも含める。D 状態は主に ディスク I/O やネットワークストレージの応答待ち で発生する。

このため、次のような一見矛盾した状態が起こりうる。

  • load average 8.0 なのに CPU 使用率(us+sy)は 10% → 残りは I/O 待ちで積み上がっている
  • ストレージが遅い・NFS がハングした、といった状況で load だけが急騰する

「load average が高い = CPU が忙しい」とは限らない。CPU 飽和と I/O 待ちは原因も対処も別物なので、まず切り分ける。

CPU 待ちか I/O 待ちかをどう見極めるのか?

結論: vmstat 1 の r 列(実行待ち)と b 列(I/O 等で停止)、top の %wa(iowait)を見る。r が大きければ CPU 飽和、b と wa が大きければ I/O 待ち。

手順 1: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
 6  0      0 124560  20480 890120    0    0     8    12  210  430 78 12 10  0  0
 5  0      0 124100  20480 890120    0    0     0     0  198  410 80 11  9  0  0

注目する列は 2 つ。

  • r(runnable):CPU を実行中/実行待ちのプロセス数。コア数より継続的に大きい → CPU 飽和
  • b(blocked):I/O 等で割り込み不可スリープ中のプロセス数。大きい → I/O 待ち

CPU 欄の wa(iowait、I/O 完了待ちの割合)も併せて見る。上の例は r=6 でコア数 4 を超え、wa=0 なので CPU 飽和型

手順 2:top で内訳を確認する

$ top

ヘッダ行の CPU 内訳を見る。

%Cpu(s): 78.0 us, 12.0 sy,  0.0 ni, 10.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
  • us(user)+ sy(system)が高い → CPU 飽和。P キーで CPU 使用率順に並べ替えて犯人プロセスを特定
  • wa(iowait)が高い → I/O 待ち。CPU はディスク等の完了を待っている

手順 3:I/O 待ちの D 状態プロセスを名指しする

wa が高いときは、どのプロセスが I/O で詰まっているかを ps の状態列(STAT)で探す。

$ ps -eo pid,stat,comm,wchan | awk '$2 ~ /D/'
  1842 D    mysqld          wait_on_page_bits
  1990 D+   dd              balance_dirty_pages

STATD(uninterruptible sleep)のプロセスが I/O 待ちの当事者。wchan(カーネル内の待ち場所)も原因のヒントになる。

手順 4:iostat でディスク側を裏取りする

$ iostat -x 1 3
Device   r/s     w/s   rkB/s   wkB/s  await  aqu-sz  %util
sda      8.00  420.00   64.00 51200.0  85.20    9.80   99.6
  • %util が 100% 近い → そのデバイスが飽和(これ以上 I/O を捌けない)
  • await(1 I/O あたりの平均応答ミリ秒)が大きい → ディスクが遅い
  • aqu-sz(平均キュー長)が大きい → I/O が滞留

%util ほぼ 100% は I/O 待ち型の決め手。

判定チートシート

  • vmstatr 高・wa 低 → CPU 飽和
  • vmstatb 高・top の wa 高・iostat%util 高 → I/O 待ち
  • どちらも高い → CPU と I/O が連鎖(DB の全表スキャン等)。両面から見る

CPU 飽和が原因のときの対処は?

結論: top/ps で CPU を食うプロセスを特定し、暴走なら nice での優先度調整や停止、慢性的ならコア増設・処理の分散・コード最適化を検討する。

$ ps -eo pid,pcpu,comm --sort=-pcpu | head
  • 単発の暴走 → 原因プロセスを停止、または renice で優先度を下げる
  • 慢性的にコア数を超える → スケールアップ(コア増設)・処理の並列分散・アルゴリズム改善
  • 特定時間帯だけ → cron / バッチの集中を疑い、実行時刻を分散

詳細な犯人特定の手順は CPU100%の調べ方 を参照。

I/O 待ちが原因のときの対処は?

結論: iostat で飽和デバイスを特定し、I/O を出しているプロセスを iotop で見つける。ログ肥大・スワップ多発・遅いストレージが典型要因。

$ sudo iotop -o
  • 特定プロセスの書き込みが多い → ログ出力過多・全表スキャン等を疑う
  • si/so(vmstat のスワップ列)が動いている → メモリ不足でスワップ多発。メモリ不足の調べ方
  • ストレージ自体が遅い → デバイス交換・I/O スケジューラ見直し・読み書きの削減

ディスク I/O の深掘りは ディスクI/Oが遅いときの調べ方 を参照。

やってはいけないこと

  • load average の 絶対値だけ で判断する(コア数を必ず併記)
  • wa を無視して CPU 増設に走る(I/O 待ちはコアを足しても解決しない)
  • D 状態プロセスを kill -9 で無理に止めようとする(I/O 完了まで止まらないことが多い)

まとめ