htopとiotopが本当に必要になるとき
ある夜、突然サーバーの動作が重くなりました。レスポンスタイムが200msから3秒に跳ね上がり、4コアのマシンなのにCPUロードアベレージが8.0まで上昇。topを開いて眺めてみましたが、画面がめまぐるしく変わり、どのプロセスがリソースを食い尽くしているのかわかりません。htopに切り替えた瞬間、原因がすぐわかりました。バックアップのcronジョブがrsyncとMySQL dumpを同時実行し、ディスクI/Oを100%まで押し上げていたのです。確認のためにiotopも必要でした。
Ubuntu 22.04 / 4GB RAMのサーバーにこの2つをインストールしてから、トラブル対応時間が手探りの30分から5分以内に短縮されました。大げさではありません。適切なツールを適切な用途に使っているだけです。htopでプロセスごとのCPU/RAMを確認し、iotopでプロセスごとのディスクI/Oを把握する—それだけです。
この記事はすぐ実践で使えることだけを書いています — manページのコピーではありません。
htopとiotopのインストール
Ubuntu/Debianの場合
sudo apt update
sudo apt install htop iotop -y
CentOS/AlmaLinux/RHELの場合
sudo dnf install htop iotop -y
# またはyumを使う場合(CentOS 7以前):
sudo yum install htop iotop -y
インストール後のバージョン確認
htop --version
# htop 3.2.2
iotop --version
# iotop 0.6
注意:iotopはカーネルがCONFIG_TASK_IO_ACCOUNTINGをサポートしている必要があります。最近のほとんどのディストリビューションでは最初から対応しています。“kernel not configured for task I/O accounting”というエラーが出た場合、最も手っ取り早い解決策はiotop-cをインストールすることです。C言語で書き直されたバージョンで、要件が少なく、オリジナルよりも積極的にメンテナンスされています。
htopの詳細設定と使い方
htopの画面の読み方
すべてのユーザーのプロセスを表示するにはsudoでhtopを実行します。sudoなしでは自分のプロセスしか見えません:
sudo htop
レイアウトは明確に3つのエリアに分かれています:
- ヘッダー(上部):CPUバー、メモリ、スワップ、ロードアベレージ、稼働時間
- プロセスリスト(中央):各種パラメータの列を持つプロセス一覧
- フッター(下部):キーボードショートカット
CPUバーセクション:各バーはコア(またはスレッド)を表します。緑色 = ユーザープロセス、赤色 = カーネル/システム、黄色 = nice(低優先度プロセス)。赤いバーが多くを占めている場合、カーネルの処理が多い兆候です — 通常はI/O waitまたは割り込みが原因です。
注目すべき重要な列
- PID:プロセスID
- USER:プロセスの所有者
- PRI/NI:優先度とNice値(NIは-20から19、低いほど優先度が高い)
- VIRT/RES/SHR:仮想/常駐/共有メモリ。RESが実際に注目すべき数値 — プロセスが使用中の物理RAMです
- S:状態 — R(実行中)、S(スリープ)、D(ディスク待ち — ディスク待ちのプロセス、I/Oボトルネックの可能性)
- CPU%:このプロセスのCPU使用率
- MEM%:総RAM使用率
- TIME+:累積CPU使用時間
- COMMAND:コマンド名
実用的なキーボードショートカット
| キー | 機能 |
|---|---|
F6 または > |
ソートする列を選択(デフォルトはCPU%) |
F4 または \ |
プロセス名でフィルタリング |
F5 |
ツリービューに切替 — 親子プロセス関係を視覚化 |
F9 |
プロセスをkill(シグナルを選択) |
Space |
プロセスをタグ付け(複数プロセスを一括kill) |
u |
ユーザーでフィルタリング |
H |
ユーザースレッドの表示/非表示 |
t |
ツリービューの切替 |
表示列のカスタマイズ
F2(Setup)→ Columns と進んで、列を自由に追加・削除できます。私はよくIO_READ_RATEとIO_WRITE_RATEを追加してプロセスリストの中でディスクアクティビティを直接確認できるようにしています — 別途iotopを開く必要がなくなります。設定は~/.config/htop/htoprcに保存されます。
I/O列を有効にした~/.config/htop/htoprcの例:
# 現在の設定を表示
cat ~/.config/htop/htoprc
# htoprcの重要な設定箇所
fields=0 48 17 18 38 39 40 2 46 47 49 1
# 48 = IO_READ_RATE, 49 = IO_WRITE_RATE
iotopの設定と使い方
iotopの基本的な実行
iotopはすべてのプロセスのI/Oアカウンティングを読み取るためにroot権限が必要です:
sudo iotop
すぐに結果が表示されます:各プロセスの読み書き速度と、システム全体のスループット合計がヘッダーに表示されます。
実用的なオプション
# I/Oアクティビティがあるプロセスのみ表示(アイドルプロセスを除外)
sudo iotop -o
# バッチモード — テキスト出力。ログやgrepに便利
sudo iotop -b -o -n 5
# -b: バッチモード、-n 5: 5回スナップショット取得後に終了
# 特定のユーザーのプロセスのみ表示
sudo iotop -u www-data
# 組み合わせ: only + batch + 2秒間隔
sudo iotop -o -b -d 2 -n 10
iotopのパラメータの読み方
- DISK READ / DISK WRITE:プロセスの現在のI/O速度(KB/s、MB/s)
- SWAPIN:プロセスがスワップされている時間の割合 — 0より大きい場合はRAMが不足し始めています
- IO>:プロセスがI/O待ちでブロックされている時間の割合 — ボトルネック検出に最も重要な数値
- Total DISK READ / WRITE(1行目):システム全体の合計スループット
- Actual DISK READ / WRITE(2行目):ハードウェアへの実際のスループット(カーネルバッファ後)
Actual DISK READがTotal DISK READよりも大幅に高い場合、カーネルが先読み(readahead)を行っています — これは正常な動作です。あるプロセスのIO>が常に50%を超えている場合、そのプロセスはI/Oボトルネックを起こしています。
実践的なチェックとモニタリング
シナリオ1:CPU消費の多いプロセスを特定する
# htopを開き、CPU%でソート(デフォルト)
sudo htop
# F6を押す → PERCENT_CPUを選択 → Enter
# CPU消費の多いプロセスが上位に表示される
php-fpmやmysqldが継続してCPUの80%以上を占めている?すぐにスロークエリログを確認しましょう — フルスキャンが走っているクエリが潜んでいることがほとんどです。
シナリオ2:メモリリークを調査する
# RES(常駐メモリ)でソート
# htopでF6を押す → M_RESIDENTを選択
# または'm'キーでメモリソートをトグル
RESが一方的に増え続けて決して下がらない — それはメモリリークです。追加の診断は不要です。私はかつてNode.jsアプリが6時間で200MBから3GBまで増加するのを目撃しました。htopのメモリソートで一発でわかりました。
シナリオ3:iotopでサーバーラグを診断する
# onlyモードでiotopを起動し、アクティブなI/Oプロセスを表示
sudo iotop -o
# 別のターミナルで同時に、ロードアベレージを確認
watch -n 1 'cat /proc/loadavg'
ロードアベレージが高いのにhtopのCPU%が低い?犯人はほぼ確実にI/Oです。iotop -oを実行すると、ディスク待ちでブロックされているプロセスがリストの先頭に表示されます。
シナリオ4:I/Oアクティビティをログに記録して後で分析する
# iotopのログを60秒間記録(2秒間隔で30回)
sudo iotop -b -o -d 2 -n 30 > /tmp/iotop_$(date +%Y%m%d_%H%M%S).log 2>&1 &
# ログを後で確認
grep -v '^$' /tmp/iotop_*.log | head -50
I/Oが高い場合にアラートを出すシンプルなスクリプト
#!/bin/bash
# /usr/local/bin/check_io.sh
# Cron: */5 * * * * /usr/local/bin/check_io.sh
THRESHOLD=50 # MB/s
LOG=/var/log/io_alert.log
# 合計ライトレートを取得(MB/s)
WRITE_RATE=$(sudo iotop -b -o -n 1 -d 1 2>/dev/null | \
grep 'Total DISK WRITE' | \
awk '{print $9}')
if (( $(echo "$WRITE_RATE > $THRESHOLD" | bc -l) )); then
echo "$(date '+%Y-%m-%d %H:%M:%S') ALERT: Disk write ${WRITE_RATE} MB/s" >> $LOG
# 書き込みの多い上位プロセスを取得
sudo iotop -b -o -n 1 2>/dev/null | head -15 >> $LOG
fi
vmstatと組み合わせて全体像を把握する
# vmstatが2秒ごとにパラメータを出力
vmstat 2
# 'b'列: I/O待ちでブロックされているプロセス数
# 'wa'列: I/O wait%(20%以上が続く場合はディスクがボトルネック)
# 'si/so'列: スワップin/out(継続して0より大きい場合はRAM不足)
トラブル発生時に私がよく使うワークフロー:まずvmstat 2で全体像を確認 → waが高ければiotop -oでプロセスを特定 → CPUロードが高ければhtopでCPU順にソート → メモリが少なければRES順にソート。この3ステップで問題がすぐに特定できます。
数ヶ月の経験から学んだこと:瞬時の数値だけを見ていてはいけません。htopとiotopはあくまでスナップショットです。本当のボトルネックはピーク時間帯に現れることが多く、あなたが画面を見ているタイミングとは限りません。sarやNetdataと組み合わせて履歴データを持ちましょう。問題がいつ発生したかがわかれば、htop/iotopがドリルダウンの強力なツールになります。

