待ってるのに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