- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに
- 1. ツールを選ぶ順番 — USE 方法論
- 2. top と htop — 錯覚を作る 3 つの地点
- 3. vmstat — システム全体を 1 行で要約する
- 4. mpstat と pidstat — 範囲を絞る 2 つのツール
- 5. iostat — await を見て %util は疑う
- 6. sar — 過ぎ去った時間を巻き戻す
- 7. ネットワーク — スループット、キュー、再送
- 8. perf — どの関数で時間を使っているのか
- 9. ツール選択の要約表
- クイズ: 理解度を確認しましょう
- おわりに
- 参考資料
- 関連記事
はじめに
性能ツールを学ぶことと、性能ツールの出力を読むことは別のことです。iostat -x を打てる人は多いですが、%util が 100 パーセントという結果を見て「では、このディスクは飽和なのか」に正確に答えられる人は少ないです。man ページがその値は最新の SSD では飽和を意味しないと明記しているにもかかわらず、そうなのです。
このブログには Linux 性能エンジニアリングガイド がすでにあり、あの記事はプロファイリング手法と eBPF、フレームグラフ、カーネルチューニングを幅広く扱っています。この記事はそれと重ならない地点を掘ります。各ツールが出力する列の 1 つ 1 つが何を意味し、どの値が錯覚を作るのか がテーマです。ツールを新しく紹介する記事ではなく、すでに知っているツールの出力を読み違えないようにするための記事です。
基準となる環境は sysstat 12 以上、カーネル 5.x 以上です。列名は sysstat のバージョンによって変わるので (例: 以前の avgqu-sz が aqu-sz に変更)、出力が違う場合はインストールされているバージョンの man ページを確認してください。
1. ツールを選ぶ順番 — USE 方法論
やみくもに top から立ち上げる習慣を直す最も簡単な方法は USE チェックリストです。すべての資源について 使用率 (Utilization)、飽和度 (Saturation)、エラー (Errors) の 3 つを問います。
| 資源 | 使用率 | 飽和度 | エラー |
|---|---|---|---|
| CPU | mpstat -P ALL | vmstat の r、pidstat の %wait | dmesg (MCE) |
| メモリ | free -m | vmstat の si/so、ページスキャン | dmesg (OOM) |
| ディスク | iostat -xz | aqu-sz、await | dmesg、smartctl |
| ネットワーク | sar -n DEV | nstat の再送/ドロップ | ip -s link |
| ファイルハンドル | /proc/sys/fs/file-nr | ulimit -n への到達 | ログの EMFILE |
この表の価値は 飽和度の列 にあります。使用率だけを見れば「CPU 60 パーセントだから余裕がある」と判断しますが、実行キューがコア数の 3 倍なら、すでに遅延が発生しています。使用率は平均であり、飽和度は待ちです。ユーザーが感じるのは待ちのほうです。
2. top と htop — 錯覚を作る 3 つの地点
top は最初に立ち上げるツールですが、読み違えるのも最も簡単です。
top -b -n 1 | head -20
top -H -p 1234
top -o %MEM
-b はバッチモードでログに残すのに向いており、-H はスレッド単位の表示、-o はソート基準の指定です。
錯覚 1: %CPU はコア 1 つが基準です。8 コアのシステムで 1 つのプロセスが 800 パーセントを示すことがあります。100 パーセントを超える値を見て驚く必要はありません。top の実行中に Shift+I を押すと Irix モードが切れ、全コア基準の値に変わります。
錯覚 2: VIRT は予約された仮想アドレス空間です。Java や Go のランタイムは、実際には使わない大きな領域をあらかじめマップします。メモリの判断は RES で、より正確には PSS で行うべきです。
錯覚 3: 最初の画面の %CPU は起動以降の累積値 です。top を開いた直後にキャプチャした値には意味がなく、少なくとも 2 回目の更新から読む必要があります。
メモリをプロセスごとに正確に見るには、共有ページを按分して計算する PSS のほうが適しています。
sudo grep -H '^Pss:' /proc/1234/smaps_rollup
RSS はそのプロセスが物理メモリに載せているページの総量ですが、複数のプロセスが共有するライブラリのページをそれぞれで丸ごと数えてしまいます。ワーカープロセスを 20 個立ち上げる Web サーバーで RSS を単純に合計すると、実際のメモリ使用量の数倍になるのはこれが理由です。PSS は共有ページを参照プロセス数で割って配分するので、PSS の合計は実際の使用量にはるかに近くなります。容量の見積もりやコンテナのメモリ上限を決めるときは、必ず PSS を基準に判断してください。
htop を使うなら、表示オプションでスレッド表示と階層構造の表示をオンにしておくほうがよいです。特にコンテナの中で実行するとホスト全体ではなく名前空間の中のプロセスだけが見えるので、ホストの観点からの資源競合を判断するときはホスト側で再度確認する必要があります。
3. vmstat — システム全体を 1 行で要約する
vmstat 1 は性能ツールのなかで情報密度が最も高いです。man ページが明記しているとおり 最初のレポートは最後の再起動以降の平均値 なので、必ず 2 行目から読みます。
vmstat -w 1 10
vmstat -s
vmstat -d
-w は幅の広い出力、-s はイベントカウンタのテーブル (繰り返しなし)、-d はディスク統計です。
読むルールを整理するとこうなります。
rがコア数より大きく、継続的に大きければ CPU の飽和 です。瞬間的に跳ねるのは正常です。bが 0 でなければ、I/O の完了を待っているプロセスがいるという意味です。si/soが 0 でなければ スワップが実際に起きている最中 です。swpdが大きくてもsi/soが 0 なら、過去に押し出されたページがそのまま残っているだけで現在の問題ではありません。この区別が重要です。bi/boはブロックデバイスの読み書き (KiB/s) です。cs(コンテキストスイッチ) が異常に大きければ、ロックの競合や過度なスレッドを疑います。in(割り込み) が大きければ、ネットワークトラフィックやタイマーを見ます。stはハイパーバイザに奪われた時間です。ゲストの中では解決できない問題 なので、この値が高いままならインスタンスタイプの変更や移行が答えです。
us と sy の比率も有用です。sy が us より大きければ、アプリケーションのロジックではなくシステムコール、コンテキストスイッチ、割り込み処理で時間を使っているという合図です。
4. mpstat と pidstat — 範囲を絞る 2 つのツール
mpstat はコアごとに分けて見ます。このツールの存在理由は 平均が隠す不均衡 をあらわにすることです。
mpstat -P ALL 1 5
8 コアのうち 1 つだけが 100 パーセントなら、全体平均は 12.5 パーセントで暇に見えますが、実際にはシングルスレッドのボトルネックです。割り込みが 1 つのコアに集中している場合もここで見えます (%irq、%soft 列)。
pidstat はプロセス単位の区間統計です。top と違って 画面を消さずに出力し続けてくれるので ファイルに残すのに適しています。
pidstat -u 1 5
pidstat -r 1 5
pidstat -d 1 5
pidstat -w 1 5
pidstat -t -p 1234 1 5
各モードの列は次のとおりです。
-u:%usr、%system、%guest、%wait、%CPU、CPU。ここでの%waitは「実行準備はできているのに CPU を待った比率」です。この値が高ければプロセスが遅いのではなく CPU の競合が激しいということ なので、対応がまったく変わります。-r:minflt/s、majflt/s、VSZ、RSS、%MEM。majflt/s(メジャーフォルト) が核心 です。これはディスクからページを読んでこなければならなかった回数なので、0 でなければメモリが足りないか、ファイルキャッシュが押し出されている最中です。マイナーフォルトは正常時にも常に発生します。-d:kB_rd/s、kB_wr/s、kB_ccwr/s、iodelay。kB_ccwr/sは書き込みが取り消された量で、ファイルを書いてから消した場合などに現れます。-w: コンテキストスイッチの統計。自発的な切り替え (cswch/s) は待ちによるもので、非自発的な切り替え (nvcswch/s) はタイムスライスの使い切りによるものです。後者が多ければ CPU の競合です。-t: スレッド単位に分解します。
5. iostat — await を見て %util は疑う
iostat -xz 1 5
iostat -xmdz -p ALL 1 3
-x 拡張統計、-z 非活動デバイスの省略、-m MiB 単位、-p ALL パーティションまで、-y 最初のレポートの省略です。
主要な列の定義は次のとおりです。
r/s、w/s: マージ後に完了した 1 秒あたりの読み書き要求数。rrqm/s、wrqm/s: 1 秒あたりにマージされた要求数。この値が大きければ、カーネルがシーケンシャル I/O をうまくまとめているという意味です。r_await、w_await: キューの待ち時間を含む 平均サービス時間 (ミリ秒)。ユーザーが体感する値に最も近いです。aqu-sz: 平均キュー長。rareq-sz、wareq-sz: 平均要求サイズ (KiB)。4KiB 近辺ならランダム I/O、数百 KiB ならシーケンシャル I/O です。%util: デバイスに要求が発行されていた時間の比率。
%util に対する man ページの警告はそのまま引用する価値があります。要求を 直列に処理するデバイス では 100 パーセント近辺が飽和を意味しますが、RAID アレイや最新の SSD のように並列処理するデバイスでは、この値は性能の限界を反映しません。NVMe は数十個のキューを同時に回すので、%util 100 パーセントでも余裕が多くあります。
実務上の判断基準はこのように立てるほうが安全です。
| 状況 | 解釈 |
|---|---|
await は普段どおり、%util 100 パーセント | 正常。デバイスがよく働いている最中 |
await が急増、aqu-sz が急増 | 本物の飽和 |
await が急増、aqu-sz は低い | デバイス自体が遅くなった (ファームウェア、リモートボリューム、スロットリング) |
r/s+w/s は低いのに await が大きい | クラウドボリュームの IOPS クレジット枯渇を疑う |
クラウド環境では最後の項目が特によくあります。バーストクレジットが尽きると IOPS が急にベースラインまで落ち、要求数は少ないのに応答が遅くなります。
6. sar — 過ぎ去った時間を巻き戻す
性能問題の半分は、人がログインしたときにはすでに終わっています。sar はその瞬間を巻き戻すためのツールです。
sar -u -s 03:00:00 -e 04:00:00
sar -r
sar -q
sar -b
sar -n DEV
sar -n EDEV
sar -W
sar -f /var/log/sa/sa14 -u ALL
-uCPU、-rメモリ、-q実行キューと負荷、-bI/O 転送率、-n DEVインターフェースのスループット、-n EDEVインターフェースのエラー、-Wスワッピングの統計。-s/-eで時間区間を、-fで日付ごとのファイルを指定します。
収集ファイルのパスはディストリビューションごとに異なります。RHEL 系は /var/log/sa/、Debian/Ubuntu 系は /var/log/sysstat/ です。Debian 系は /etc/default/sysstat で収集をオンにしないとデータがたまり始めません。収集周期と保存期間は /etc/sysstat/sysstat (Debian) または /etc/sysconfig/sysstat (RHEL) で調整します。
デフォルトの 10 分周期は瞬間的なスパイクを取り逃します。秒単位のイベントを捕まえる必要があるなら、収集周期を 1 分に縮めるか、別の常時収集を付ける必要があります。その代わりディスク使用量と収集の負荷が増える点を考慮してください。
7. ネットワーク — スループット、キュー、再送
スループットは sar -n DEV、エラーは sar -n EDEV、ソケットの状態は ss、カーネルのカウンタは nstat です。
sar -n DEV 1 5
ip -s link show eth0
nstat -az | grep -i -E 'retrans|listen|prune|collapse'
ss -tin state established | head -20
ss -i はソケットごとの TCP 内部情報を見せてくれます。ここから rtt、cwnd、retrans の値を読むことができます。RTT が大きく cwnd が小さければ、帯域が余っていてもスループットが出ません。遅延帯域幅積がウィンドウサイズに閉じ込められた典型的な状況です。
nstat のカウンタのうち実務でよく使うものは次のとおりです。
TcpExtListenOverflows、TcpExtListenDrops: accept キューが溢れました。アプリケーションが accept に追いつけないか、バックログが小さいかです。TcpRetransSegs: 再送。全送信に対する比率で見て初めて意味があります。TcpExtTCPRcvCollapsed、TcpExtPruneCalled: 受信バッファの圧迫。
インターフェースレベルのドロップは ip -s link の RX errors/dropped で見ます。ここが増えるなら、カーネルより上ではなく NIC やリングバッファを見る必要があります。
8. perf — どの関数で時間を使っているのか
ここまで来て「CPU を使っているのは分かるが、中で何をしているのか分からない」となったら perf の出番です。
sudo perf top
sudo perf stat -d -p 1234 -- sleep 10
sudo perf record -F 99 -g -p 1234 -- sleep 30
sudo perf report --stdio | head -40
perf top: リアルタイムで最も多く CPU を使っているシンボルを見せてくれます。perf stat: コマンドを実行した区間のハードウェアカウンタを要約します。IPC (instructions per cycle)、キャッシュミス、分岐予測の失敗を見ます。IPC が 1 よりかなり低ければ CPU がメモリを待っている最中 だという強い合図です。perf record -g: コールスタックを含めてサンプルをファイルに残します。-F 99は 1 秒あたり 99 回のサンプリングで、タイマーと拍子が重なるのを避けるために 100 ではなく 99 を使います。
コンテナやクラウドで perf が動かない場合、カーネルの観測許可レベルのせいかもしれません。
cat /proc/sys/kernel/perf_event_paranoid
値が 2 以下でなければ一般的なプロファイリングはできず、コンテナでは別途の権限付与が必要です。本番サーバーでこの値を下げるのはセキュリティ上の決定 なので、勝手に変えずポリシーに従って処理してください。正確な権限の要件は、使用中のディストリビューションとカーネルバージョンのドキュメントで確認してください。
シンボルが疑問符だけで見えるなら、デバッグシンボルのパッケージがないということです。RHEL 系は debuginfo パッケージ、Debian 系は dbgsym リポジトリを追加する必要があります。
9. ツール選択の要約表
症状から出発してツールを選ぶ表です。実際にはこの順番で下りていけば、ほとんどの場合に答えが出ます。
| 症状 | 一次ツール | 確認する値 | 次の段階 |
|---|---|---|---|
| 全体的に遅い | vmstat 1 | r、wa、si/so、st | 該当資源の専用ツール |
| 特定のプロセスだけ遅い | pidstat -u -t | %wait、%system | perf record -g |
| 応答遅延が跳ねる | iostat -xz 1 | r_await、w_await | pidstat -d |
| メモリ不足のようだ | free -m、pidstat -r | available、majflt/s | smaps_rollup の PSS |
| コネクションが張れない | ss -s、nstat | ListenOverflows | バックログとワーカー数の調整 |
| CPU は遊んでいるのに負荷だけ高い | ps の D 状態フィルタ | wchan | ストレージ層の調査 |
| 過去の時点を再現できない | sar -f | 該当時刻の区間 | 常時収集の周期短縮 |
この表を壁に貼っておくよりよい方法は、チームで実際に経験した障害を 1 行ずつ追加していくことです。組織ごとによく遭遇するボトルネックが違うので、そのリストのほうがはるかに正確になります。
測定でよく抜け落ちる最後のピースは 比較対象 です。今の応答時間が 200 ミリ秒だという事実だけでは、それが良いのか悪いのか分かりません。普段の値が 40 ミリ秒だったなら深刻な状況であり、普段が 220 ミリ秒だったなら何事でもありません。だからこそ性能ツールを導入するときに最初にやるべきことは閾値を決めることではなく、平常時の値を数日間記録してベースラインを作ること です。ベースラインがなければ、すべての数字は解釈不能な状態のまま残ります。
コンテナ環境ではもう一枚必要です。コンテナの中で見た free や nproc はホストの値をそのまま見せる場合が多く、実際の制限は cgroup に掛かっています。制限と実際の使用量は cgroup v2 のファイルから直接読むのが確実です。
cat /sys/fs/cgroup/memory.max
cat /sys/fs/cgroup/memory.current
cat /sys/fs/cgroup/cpu.max
cat /sys/fs/cgroup/cpu.stat
cpu.stat のスロットリング関連カウンタが増え続けるなら、ホストの CPU が暇でもコンテナは周期的に止まっているということです。この場合ホストで観測した CPU 使用率は低く出るので、コンテナの中の遅延の原因をホストの指標だけで見つけることは絶対にできません。
クイズ: 理解度を確認しましょう
クイズ 1: vmstat で swpd が 2GB なのに si と so はずっと 0 です。メモリの問題でしょうか。
答え: 現在進行中の問題ではありません
解説: swpd はスワップに入っている総量であり、si/so は 1 秒あたりのスワップイン/アウトの速度です。過去のある時点で押し出されたページがそのまま残っているだけで、今スワッピングが起きていないなら性能への影響はありません。むしろあまり使わないページがスワップへ出て、その場所をページキャッシュが使うのは望ましい状態です。問題は si/so が継続的に 0 でなくなったときに始まります。
クイズ 2: pidstat -u で %wait が 40 パーセントです。このプロセスに CPU をもっと与えれば解決するでしょうか。
答え: このプロセスの問題ではなく、システム全体の CPU 競合の問題です
解説: %wait は「実行準備はできているのに CPU を受け取れず待った比率」です。つまりこのプロセスは働く準備ができているのに、他のプロセスに押しのけられたのです。対応はこのプロセスを最適化することではなく、全体の負荷を減らすか、コアを増やすか、スケジューリングの優先度を調整する方向です。
mpstat -P ALL 1 5
pidstat -u 1 5
クイズ 3: NVMe ディスクの %util が 100 パーセントに固定されています。ストレージを増設すべきでしょうか。
答え: まだ判断できません。await と aqu-sz を見る必要があります
解説: iostat の man ページは「要求を並列に処理する RAID アレイや最新の SSD では %util が性能の限界を反映しない」と明記しています。NVMe はマルチキューで動作するので常に要求が 1 つくらいは発行されており、その結果 %util は簡単に 100 パーセントになります。判断の基準は応答時間です。
iostat -xz 1 5
r_await と w_await が普段どおりの水準なら、増設する理由はありません。
クイズ 4: 8 コアサーバーのロードアベレージが 4 なのにユーザーは遅いと言います。何を確認しますか。
答え: コアごとの分布と単一コアの飽和の有無をまず確認します
解説: 負荷 4 は 8 コア基準では半分ですが、その負荷が 1 つのコアに集中しているなら、そのコアを使う要求はすべて待たされます。
mpstat -P ALL 1 5
pidstat -t -p <PID> 1 5
mpstat で特定のコアだけが 100 パーセントならシングルスレッドのボトルネックであり、コアを増やしても解決しません。割り込みが 1 つのコアに集中している場合なら %soft 列が高く出ます。
クイズ 5: perf stat の結果で IPC が 0.3 です。何を意味しますか。
答え: CPU が命令を実行できずメモリを待っている時間が長いという意味です
解説: IPC (instructions per cycle) が低いというのは、サイクルを消費しながらも命令を少ししか処理しなかったという意味です。主な原因はキャッシュミス、メモリ遅延、分岐予測の失敗です。この場合、アルゴリズム自体の命令数を減らすことよりも データのアクセスパターンを改善するほう (データ構造の配置、シーケンシャルアクセス、キャッシュ局所性) が効果的です。
sudo perf stat -d -p 1234 -- sleep 10
-d オプションがキャッシュ関連のカウンタも一緒に見せてくれます。
クイズ 6: 障害が深夜 3 時に発生し、朝に出勤しました。どのツールから使いますか。
答え: sar でその時間帯の収集データを巻き戻します
解説: リアルタイムのツールは、すでに過ぎ去った事象には無力です。
sar -q -s 02:50:00 -e 03:30:00
sar -u -s 02:50:00 -e 03:30:00
sar -r -s 02:50:00 -e 03:30:00
sar -n DEV -s 02:50:00 -e 03:30:00
journalctl --since '2026-08-15 02:50' --until '2026-08-15 03:30' -p warning
収集ファイルがなければ、今回の障害からは何も分かりません。だからこそ sysstat の収集をオンにしておくことが、事後対応ではなく事前準備なのです。
おわりに
性能ツールの出力は事実を語ってくれますが、結論を語ってくれるわけではありません。%util 100 パーセントは事実であり、「ディスクが飽和だ」は解釈です。その解釈がデバイスの種類によっては間違いうると知っていることが、ツールを使う能力です。
覚えておくべき原則 3 つとして整理します。第一に、使用率より飽和度を先に見る。第二に、平均が隠す不均衡をコアごと・プロセスごとに割って見る。第三に、過ぎ去った時間を見られなければどんなツールも役に立たないので、常時収集をオンにしておく。
参考資料
- vmstat(8) — man7.org (2026-08-15 確認)
- iostat(1) — man7.org (2026-08-15 確認)
- pidstat(1) — man7.org (2026-08-15 確認)
- ss(8) — man7.org (2026-08-15 確認)
- dmesg(1) — man7.org (2026-08-15 確認)
関連記事
- 前の記事: Linux 障害対応コマンド完全ガイド
- 次の記事: プロセスとシグナル完全ガイド
- Linux 性能エンジニアリング完全ガイド — eBPF とフレームグラフまで
- Linux カーネルパラメータチューニングガイド — 測定の次の調整
- Linux ターミナル — コマンドをブラウザで練習
- Linux コマンドクイズ — オプションの記憶を点検