🕰️

待ってるのにCPUが悲鳴!? IOWaitの正体をアラート設計と考える

に公開

はじめに

「IOWait??このアラート必要?そもそも待ち時間が、なぜCPU利用率に影響するの?」

アラートを見直しててこう思ったことありませんか?Idleなんとかは分かるんだけど、別にFire状態になったことないし、正しい閾値設定もわからん、と。

ノイマン型のコンピュータアーキテクチャを考えてみると、これは単なる待ち時間と捉えると勿体無いと感じました。アラート設計と共に、少しだけ整理してみます。

IOWaitの正体

IOWaitとは「Input/Output Wait」の略。CPUがI/O操作の完了をひたすら待ち続けている時間のことです。文字面からもなんとなく分かる気がします。

例:

  • ディスクからファイルを読む
  • ディスクにファイルを書く
  • ネットワーク通信
  • オーディオ出力の再生用バッファにデータを書き込む
  • ディスプレイに描画するためにフレームバッファ(GPUメモリ)へ転送
  • USBメモリへのアクセス

現代の1GHz 64bit CPUは1秒間に10億回の命令を実行します(1周期:1ナノ秒)。対して、昔ながらのHDDはデータを読み出すのに数ミリ秒。それほどまでに、CPUにとってI/Oは遅い処理なのです

なぜCPU使用率の文脈で語られるのか?

「IOWaitはI/Oの待ち時間話なのに、なんでCPU使用率に混じってるんだ?」

次はこう思いました。Linuxカーネルの設計思想が関わる話らしい。(Macだと両方まとめてidleに入る)

CPU使用率は時間の使い方を表現する↓

CPU時間 = User + System + IOWait + Idle + その他

「じゃあこれ、何の時間?」ってなりますよね。実は、CPUは1秒間を細かく区切って、それぞれの時間を何に使ったかを記録してます!

CPU時間の内訳:

  • User: アプリケーションがガリガリ計算してる時間(例:Excelで計算、ゲームの描画処理)
  • System: OSが裏で管理作業してる時間(例:メモリ管理、ファイルシステム操作)
  • IOWait: やりたい仕事があるのに、I/O待ちで手が止まってる時間
  • Idle: 本当にやることがない平和な時間(例:何もアプリを起動してない状態)

topコマンドで例を出すなら、

%Cpu(s):  5.2 us, 2.1 sy, 0.0 ni, 85.4 id, 7.3 wa

この「wa」がIOWaitです。Cpu(s)という表記もあって、CPU時間の内訳を表すのはしっくりきそうです。

待ってるなら別の仕事すればいいじゃん問題

ここがカギな気がします。

マルチタスクOSなので、別のプロセスが走れるなら OS は切り替えて実行します。でも、「全ての CPU コアが I/O 待ちしてる」or「実行できるタスクが他にない」or「スレッドやプロセスに依存関係がある」場合、CPUは遊んでしまいます。その時間が「iowait」として積み上がります。

このとき「ただの idle」じゃなく「仕事したいのに I/O が遅いせいで遊んでる」と OS が判断するから、iowait にカウントされるんです。

IOWaitが高い時と低い時の状態

IOWaitが高い時(20%以上)

IOWaitが高い状況の理解は比較的簡単。これはプロセスやスレッドの依存関係からIOを待たないけど、runnableな仕事がなく大渋滞!って感じですね。CPUが「動きたいのに動けない〜」って悲鳴を上げてます。

症状はこんな感じ:

  • アプリケーションがもさい(プロセスの負荷はそこまでないはずなのに)
  • データベースクエリが遅い
  • ファイルコピーが終わらない

よくある犯人リスト:

  • ログファイル肥大化:書き込みが重すぎて現場が大混乱
  • データベース暴走犯:フルテーブルスキャンで現場を荒らし回る
  • バックアップ処理:深夜に大量データを持ち逃げ
  • メモリ不足スワップ:メモリが足りなくてディスクに逃す

IOWaitが低い時(5%以下)

IOWaitが低い時、これはシステムが絶好調で回ってる証拠

ただし、実際は油断は禁物です:

  • 他のCPU使用率(UserやSystem)が高い場合は、別の悪者が潜んでる
  • あまりにも低すぎる場合は、I/O処理がほぼ発生してない可能性(これはこれで心配)

まとめ

IOWaitがアラート設計でどう語られるべきか?を整理してみました。これからも、メトリクスの意味について考えていこうと思います。
情報学を学び直さないと...。

Discussion