【Linux】topコマンドでリアルタイム監視する方法|%Cpuの見方・-bでスクリプト化・重いプロセス特定

【Linux】topコマンドでリアルタイム監視する方法|%Cpuの見方・-bでスクリプト化・重いプロセス特定 Linux

topは、サーバーの状態をリアルタイムに監視するコマンドです。free・uptimeが「その瞬間の数値」を一度だけ表示するのに対し、top数秒ごとに自動更新しながら、CPU・メモリの使用状況と、動いているプロセスの一覧を表示し続けます。「サーバーが重い」というとき、何が原因なのかを突き止めるための最初の一手です。

topは情報量が多く、初めて見ると圧倒されます。しかし見るべき場所は決まっています。この記事では、実機のLinuxで実際に負荷をかけて数値が動く様子を確認し、さらに稼働中の本番サーバーの実データも使いながら、topの読み方と、スクリプトで使える-b(バッチモード)を整理します。

先に結論

  • topで起動、qで終了。数秒ごとに自動更新されます。
  • 上部にload average・Tasks・%Cpu・メモリ、下部にプロセス一覧が表示されます。
  • %Cpu(s)id(アイドル)を見れば、CPUに余裕があるか一目で分かります。
  • top -b -n 1で1回だけ出力でき、スクリプトやログ保存に使えます。
  • -o %CPU-o %MEMで、重いプロセスを並べ替えて特定できます。
  • load averageが高くてもCPUがアイドルなこともあります(I/O待ちなど)。

数値を一度だけ見るならfree・uptime、プロセスの終了はps・kill、ディスクはdu・dfもあわせて参考になります。

スポンサーリンク

topの画面構成

topを実行すると、画面が上部の「サマリー領域」下部の「プロセス一覧」に分かれます。まずは上部の5行の意味を押さえましょう。

top の画面構成
top      # 起動(q キーで終了)

# top - 10:23:02 up 0 min,  0 users,  load average: 0.00, 0.00, 0.00
#   ↑現在時刻  ↑稼働時間            ↑1分/5分/15分の平均負荷
# Tasks:   7 total,   1 running,   6 sleeping,   0 stopped,   0 zombie
#   ↑プロセス数の内訳(running=実行中、zombie=ゾンビ)
# %Cpu(s):  4.1 us,  0.0 sy,  0.0 ni, 95.9 id,  0.0 wa, ...
#   ↑CPU使用率の内訳(後述)
# MiB Mem : 31683.6 total, 31010.2 free, 408.9 used, 264.6 buff/cache
# MiB Swap:  8192.0 total,  8192.0 free,   0.0 used. 30975.0 avail Mem
#   ↑メモリとスワップ(free コマンドと同じ内容)

#     PID USER  PR  NI  VIRT  RES  SHR S  %CPU  %MEM  TIME+  COMMAND
#   ↑ここから下がプロセス一覧(既定はCPU使用率順)

実機でtopを実行すると、1行目に時刻・稼働時間・load average2行目にプロセス数の内訳running=実行中、zombie=終了処理が済んでいないゾンビプロセス)、3行目にCPU使用率4〜5行目にメモリとスワップが表示されました。メモリの内容はfreeコマンドと同じで、avail Mem(=available)が実質的に使えるメモリです。そして下部にプロセス一覧が、既定ではCPU使用率の高い順に並びます。

【重要】%Cpu(s)行の読み方

topで最も重要なのが%Cpu(s)です。CPUの時間が何に使われているかの内訳を示します。特にid(アイドル)wa(I/O待ち)が重要です。

%Cpu(s) の各項目
%Cpu(s):  4.1 us,  0.0 sy,  0.0 ni, 95.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

# us (user)   … ユーザープログラムの処理(アプリの計算など)
# sy (system) … カーネルの処理(システムコールなど)
# ni (nice)   … 優先度を変更したプロセスの処理
# id (idle)   … 何もしていない=空き(★これが大きいと余裕あり)
# wa (iowait) … ディスクI/O待ち(★大きいとディスクがボトルネック)
# hi/si       … ハードウェア/ソフトウェア割り込み
# st (steal)  … 仮想化環境でホストに奪われた時間(VPSで重要)

見るべき優先順位はこうです。まずid(アイドル)——これが大きければCPUに余裕があります。次にwa(I/O待ち)——これが大きい場合、CPUではなくディスクがボトルネックです(ディスク容量や遅いストレージが原因のことも)。usが高いのはアプリが計算している状態で、syが異常に高い場合はシステムコールの多発を疑います。VPSなど仮想環境ではst(steal)も要注目で、これが高いと「同居する他の利用者にCPUを奪われている」ことを意味します。

【実証】負荷をかけると数値が動く

実際にCPU負荷をかけて、topの数値がどう変わるかを確認しました。数値が実際に動く様子を知っておくと、本番で異常を見抜きやすくなります。

負荷前後の比較(実測)
# 負荷なしの状態
%Cpu(s):  0.0 us,  0.4 sy,  0.0 ni, 99.6 id, ...
#                                    ↑ほぼ100%アイドル

# CPUを使い続けるプロセスを4つ起動してから…
%Cpu(s): 25.1 us,  0.0 sy,  0.0 ni, 74.5 id, ...
#         ↑us が 25% に上昇(16コア中4コア分=25%)

# プロセス一覧(CPU使用率順)
#   PID USER  PR NI  VIRT  RES  SHR S  %CPU %MEM   TIME+ COMMAND
#    32 root  20  0  6828 3332 3072 R 100.0  0.0 0:04.29 bash
#    33 root  20  0  6828 3216 2956 R 100.0  0.0 0:04.30 bash
#    34 root  20  0  6828 3248 2988 R 100.0  0.0 0:04.30 bash
#    36 root  20  0  6828 3212 2952 R 100.0  0.0 0:04.30 bash
#         ↑負荷をかけた4プロセスが %CPU 100.0 で上位に並ぶ
負荷をかけると数値が明確に動く(実証)

実機(16コア)で、CPUを使い続けるプロセスを4つ起動してtopの変化を測定しました。負荷前は99.6 id(ほぼ完全にアイドル)でしたが、負荷をかけると25.1 us74.5 idへ変化しました。16コアのうち4コア分を使い切ったので、ちょうど25%という計算が合います。さらにプロセス一覧を見ると、負荷をかけた4つのbashプロセスが%CPU 100.0で上位に並びました。ここで注意したいのが%CPUは「1コアを100%とした値」だということです。そのためマルチコア環境では100%を超える値(200%、400%など)も表示されます——これは異常ではなく「複数コアを使っている」という意味です。「%Cpu(s)行=サーバー全体の割合」「プロセスの%CPU=1コア基準」という違いを理解しておくと、数値を正しく読めます。

【実例】load averageが高くてもCPUはアイドル

load average%Cpuは別物です。実際に稼働している本番サーバーのデータが、その違いをよく表していました。

本番サーバーの実データ
top - 10:23:30 up 8 days,  6:49,  0 users,  load average: 59.59, 66.26, 63.48
#                                                        ↑ 59.59! 高そうに見える
Tasks:   4 total,   1 running,   3 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni, 99.9 id,  0.0 wa, ...
#                                    ↑ でも 99.9% アイドル(CPUは暇)
MiB Mem : 1547455.+total, 1517980.+free,  16940.4 used,  12535.2 buff/cache
#          ↑ 約1.5TB のメモリ

# このサーバーは 256 コア → load 59.59 は約23%で余裕
# しかも自分から見える範囲のCPUはほぼアイドル
load 59.59でもCPUは99.9%アイドル(本番実測)

実際に稼働している本番サーバー(共用レンタルサーバー)でtopを実行したところ、load average: 59.59という一見驚くような数値でした。ところが同じ画面の%Cpu(s)99.9 id(99.9%アイドル)——CPUはほとんど何もしていないのです。この一見矛盾する状態には理由があります。まずこのサーバーは256コアなので、load 59.59は全体の約23%にすぎません。加えて、load averageは「CPU実行待ち」だけでなく「ディスクI/O待ち」のプロセスも含むため、CPUが暇でもI/Oが混んでいれば数値が上がります。さらに共用サーバーでは、自分のシェルから見えるプロセスは限られる(Tasks: 4 total)のに対し、load averageはサーバー全体の状態を示します。「load averageが高い=CPUが忙しい」とは限らない——この点を理解しておくと、原因の切り分けを誤りません。CPUが原因かは%Cpu(s)idwaで判断してください。

-bバッチモードでスクリプトに使う

topは対話的な画面ですが、-b(バッチモード)を使うと1回だけ結果を出力して終了できます。cronでの定期記録や、ログ保存に最適です。

-b でスクリプト向きに
# -b: バッチモード, -n 1: 1回だけ更新して終了
top -b -n 1

# CPU使用率の高い順に上位10件だけ記録
top -b -n 1 -o %CPU | head -17 > /var/log/top_snapshot.log

# メモリ使用率順に並べる
top -b -n 1 -o %MEM | head -12

# 特定ユーザーのプロセスだけ
top -b -n 1 -u www-data

# 特定のPIDだけ監視
top -b -n 1 -p 1234

# cron で定期記録する例(毎時0分)
# 0 * * * * top -b -n 1 >> /var/log/top_hourly.log

実機でも、top -b -n 1で対話画面を開かずに1回分の情報を出力でき、-o %CPUでCPU使用率順、-o %MEMでメモリ使用率順に並べ替えられることを確認しました。-u ユーザー名で特定ユーザーのプロセスだけ、-p PIDで特定のプロセスだけに絞ることもできます。-bを使えばリダイレクトでファイルに保存でき、cronで定期的にサーバー状態を記録できます。「深夜に負荷が上がる」といった調査では、この定期記録が原因究明の決め手になります。

対話画面での主なキー操作

topを対話的に使うときの覚えておくべきキーをまとめます。最低限q(終了)だけ知っていれば困りません。

キー 働き
q topを終了する(最重要)
M メモリ使用率順に並べ替え
P CPU使用率順に並べ替え(既定)
k プロセスを終了(PIDを入力)
1 CPUコアごとの使用率を表示
h ヘルプを表示

特に1(数字のイチ)は便利で、CPUコアごとの使用率を個別に表示できます。「全体では50%だが、1つのコアだけ100%で他は暇」といった並列化されていない処理を見つけられます。重いプロセスを見つけたらkで終了できますが、killコマンドを使うほうが確実です。

よくある失敗

topから抜けられない

qキーで終了できます。Ctrl+Cでも止まります。

プロセスの%CPUが100%超で驚く

%CPUは1コア基準です。マルチコアでは100%超も正常です。

load averageが高い=CPU過負荷と判断する

I/O待ちも含まれます。%Cpu(s)idwaで切り分けます。

スクリプトでtopを使おうとして固まる

対話画面のままです。-b -n 1でバッチモードにします。

waが高いのにCPUを増やそうとする

waが高いのはディスクがボトルネックです。ストレージ側を見直します。

よくある質問

Qtopを終了するには?
Aqキーを押せば終了します。Ctrl+Cでも止められます。topは数秒ごとに自動更新し続ける対話画面なので、見終わったらqで抜けてください。スクリプトで使いたい場合は、対話画面を開かずに1回だけ出力するtop -b -n 1(バッチモード)を使います。
Q%Cpu(s)のどの項目を見ればいいですか?
Aまずid(アイドル=空き)を見ます。これが大きければCPUに余裕があります。次にwa(I/O待ち)で、これが大きいとCPUではなくディスクがボトルネックです。usはアプリの処理、syはカーネルの処理、VPSなどではst(ホストに奪われた時間)も重要です。
Qプロセスの%CPUが100%を超えるのはなぜですか?
Aプロセスの%CPUは「1コアを100%」とした値だからです。マルチコア環境で複数コアを使うプロセスは、200%や400%といった値になります。異常ではありません。一方、上部の%Cpu(s)行はサーバー全体を100%とした割合なので、意味が異なります。実機でも、負荷をかけた各プロセスが100.0%と表示されることを確認しています。
Qload averageが高いのにCPUがアイドルなのはなぜですか?
Aload averageは「CPU実行待ち」だけでなく「ディスクI/O待ち」のプロセスも含むためです。実際の本番サーバーでも、load average 59.59でありながら%Cpu(s)は99.9%アイドルという状態を確認しています。加えてそのサーバーは256コアなので、load 59.59は全体の約23%にすぎません。load averageはコア数と比較し、CPUが原因かはidwaで判断してください。
Qtopの結果をログに保存するには?
Atop -b -n 1 > ファイル名とします。-bがバッチモード(非対話)、-n 1が1回だけ更新の指定です。-o %CPUでCPU順、-o %MEMでメモリ順に並べ替えられます。cronで定期実行すれば、負荷が上がる時間帯の調査に使えます。

まとめ

  • topでリアルタイム監視、qで終了
  • %Cpu(s)id(空き)とwa(I/O待ち)が最重要です。
  • プロセスの%CPU1コア基準なので100%超も正常です。
  • top -b -n 1でスクリプト・cron記録に使えます。
  • load averageが高くてもCPUがアイドルなことがあります(I/O待ち・コア数)。

topは、サーバーの「今」を映し出す監視ツールの定番です。「idとwaを見る」「%CPUは1コア基準」「スクリプトなら-b」——この3点を押さえれば、重いプロセスの特定とボトルネックの切り分けが的確にできます。free・uptimeで全体像を掴み、topで犯人を特定し、killで対処する——この流れがサーバートラブル対応の基本形です。