インフラ・DevOps
Linuxのhtop/topで見られるすべての項目の解説
Explanation of everything you can see in htop/top on Linux (peteris.rocks)
要約
この記事は、Linuxのシステム監視ツールであるhtopやtopで表示される各種項目について、その意味と見方を詳細に解説しています。特に、ロードアベージ(load average)の計算方法やCPU使用率との関係、プロセスの状態(実行中、待機中など)について掘り下げて説明し、システムパフォーマンスの理解を深めるための情報を提供します。
全文翻訳
htop解説 Linuxのhtop/topで見られるすべての項目の解説 最終更新日: 2019年11月17日 長い間、htopのすべての項目が何を意味するのか知りませんでした。ロードアベージが2コアのマシンで1.0というのは、CPU使用率が50%であることを意味すると思っていました。それは正確ではありません。そして、なぜ1.0と表示されるのでしょうか?すべてを調べてここに記録することにしました。何かを学ぶ最善の方法は、それを教えようとすることだとも言われています。
目次
Ubuntu Server 16.04 x64でのhtop
説明するhtopのスクリーンショットを以下に示します。
アップタイム
アップタイムは、システムがどれだけ長く稼働しているかを示します。uptimeコマンドを実行しても同じ情報を見ることができます:
$ uptime
12:17:58 up 111 days, 31 min, 1 user, load average: 0.00, 0.01, 0.05
uptimeプログラムはどのようにしてこれを知るのでしょうか?それは/proc/uptimeファイルから情報を読み取ります。
9592411.58 9566042.33
最初の数値はシステムが起動してからの総秒数です。2番目の数値は、マシンがアイドル状態(何もしていない状態)で過ごした時間(秒)です。この2番目の値は、複数のコアを持つシステムでは、合計値であるため、システム全体のアップタイムよりも大きくなることがあります。
どうやってこれを知ったのか?uptimeプログラムが実行時に開くファイルを確認しました。これを行うにはstraceツールを使用できます。
$ strace uptime
多くの出力が表示されます。openシステムコールでgrepできます。しかし、straceはすべて標準エラー出力(stderr)にすべてを出力するため、実際にはうまくいきません。stderrを標準出力(stdout)にリダイレクトするには2>&1を使用します。出力は次のようになります:
$ strace uptime 2>&1 | grep open
... open("/proc/uptime", O_RDONLY) = 3
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 4
open("/proc/loadavg", O_RDONLY) = 4
私が言及した/proc/uptimeファイルが含まれています。
strace -e open uptime を使用して、grepの手間を省くこともできることがわかりました。
では、ファイルのコンテンツを読み取るだけであれば、なぜuptimeプログラムが必要なのでしょうか?uptimeの出力は人間にとって読みやすい形式ですが、秒数は独自のプログラムやスクリプトで使用する場合にはより便利です。
ロードアベージ
アップタイムに加えて、ロードアベージを表す3つの数値もありました。
$ uptime
12:59:09 up 32 min, 1 user, load average: 0.00, 0.01, 0.03
これらは/proc/loadavgファイルから取得されます。straceの出力にもう一度目を向けると、このファイルも開かれていることがわかります。
$ cat /proc/loadavg
0.00 0.01 0.03 1/120 1500
最初の3つの列は、過去1分、5分、15分間の平均システムロードを表します。4番目の列は、現在実行中のプロセスの数とプロセスの総数を示します。最後の列は、最後に使用されたプロセスIDを表示します。
最後の数値から始めましょう。新しいプロセスを起動するたびに、プロセスID番号が割り当てられます。プロセスIDは通常増加しますが、枯渇して再利用される場合もあります。プロセスID 1は/sbin/initに属しており、起動時に開始されます。
/proc/loadavgのコンテンツをもう一度見て、次にsleepコマンドをバックグラウンドで起動してみましょう。バックグラウンドで起動されると、そのプロセスIDが表示されます。
$ cat /proc/loadavg
0.00 0.01 0.03 1/123 1566
$ sleep 10 &
[1] 1567
したがって、1/123は、現在1つのプロセスが実行中または実行可能であり、合計123個のプロセスがあることを意味します。htopを実行して実行中のプロセスが1つだけ表示される場合、それはhtopプロセス自体を意味します。sleep 30を実行してhtopを再度実行すると、実行中のプロセスがまだ1つだけ表示されることに気づくでしょう。これは、sleepが実行されているのではなく、スリープ中またはアイドル状態、つまり何かが起こるのを待っているためです。
実行中のプロセスとは、物理CPUで現在実行中であるか、CPUで実行される順番を待っているプロセスです。cat /dev/urandom > /dev/nullを実行すると、ランダムなバイトを繰り返し生成し、決して読み取られない特別なファイルに書き込みます。これにより、実行中のプロセスが2つになることがわかります。
$ cat /dev/urandom > /dev/null &
[1] 1639
$ cat /proc/loadavg
1.00 0.69 0.35 2/124 1679
したがって、現在2つのプロセスが実行中です(乱数生成と/proc/loadavgの内容を読み取るcat)。ロードアベージも増加していることに気づくでしょう。
ロードアベージは、一定期間の平均システムロードを表します。ロード数値は、実行中のプロセス(現在実行中または実行可能)、および中断不可能なプロセス(ディスクまたはネットワークアクティビティを待っている)の数を数えることによって計算されます。つまり、単純にプロセスの数です。
ロードアベージは、過去1分、5分、15分間のそれらのプロセスの平均数ですよね?実際にはそれほど単純ではありません。ロードアベージは、ロード数値の指数関数的に減衰する移動平均です。Wikipediaより:
数学的に言えば、3つの値すべてが常にシステムの起動以来のシステムロード全体を平均しています。それらはすべて指数関数的に減衰しますが、減衰速度は異なります。したがって、1分間のロードアベージは、過去1分間のロードの63%に、過去1分間を除く起動以来のロードの37%を加えたものになります。そのため、1分間のロードアベージが過去60秒間のアクティビティのみを含むというのは技術的には正確ではありません(過去のアクティビティの37%がまだ含まれているため)が、主に過去1分間を含んでいます。これは期待していたことですか?
ランダムな数値生成に戻りましょう。
$ cat /proc/loadavg
1.00 0.69 0.35 2/124 1679
技術的には正しくありませんが、これはロードアベージをより理解しやすくするために私が簡略化する方法です。この場合、乱数生成プロセスはCPUバウンドであるため、過去1分間のロードアベージは1.00、つまり平均1つの実行中プロセスです。私のシステムにはCPUが1つしかないため、CPUは一度に1つのプロセスしか実行できないため、CPU使用率は100%です。もし2コアあった場合、コンピュータは同時に2つのプロセスを実行できるため、CPU使用率は50%になります。CPU使用率が100%の2コアコンピュータのロードアベージは2.00になります。htopの左上隅、またはnprocコマンドを実行することで、CPUまたはコアの数を確認できます。
ロード数値には、CPU使用率にあまり影響を与えない中断不可能な状態のプロセスも含まれるため、先ほど行ったようにロードアベージからCPU使用率を推測するのは正確ではありません。これにより、ロードアベージが高いにもかかわらずCPU負荷が低いという状況が発生する理由も説明できます。しかし、mpstatのような、瞬間的なCPU使用率を表示できるツールがあります。
$ sudo apt install sysstat -y
$ mpstat
Linux 4.4.0-47-generic (hostname) 12/03/2016 _x86_64_ (1 CPU)
10:16:20 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
10:16:21 PM all 0.00 0.00 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
10:16:22 PM all 0.00 0.00 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
10:16:23 PM all 0.00 0.00 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
# ...
# kill cat /dev/urandom
# ...
10:17:00 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
10:17:01 PM all 1.00 0.00 0.00 2.00 0.00 0.00 0.00 0.00 0.00 97.00
10:17:02 PM all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
では、なぜロードアベージを使用するのでしょうか?
$ curl -s https://raw.githubusercontent.com/torvalds/linux/v4.8/kernel/sched/loadavg.c | head -n 7
/*
* kernel/sched/loadavg.c
*
* This file contains the magic bits required to compute the global loadavg
* figure. Its a silly number but people think its important. We go through
* great pains to make it work on big machines and tickless kernels.
*/
プロセス
htopの右上隅には、プロセスの総数と実行中のプロセスの数が表示されます。しかし、それはタスク(Tasks)と表示され、プロセス(Processes)ではありません。なぜでしょうか?
プロセス(Process)の別名がタスク(Task)です。Linuxカーネルは内部的にプロセスをタスクと呼びます。htopがプロセスではなくタスクを使用するのは、おそらく短く、画面スペースを節約するためでしょう。
htopではスレッド(threads)も表示できます。キーボードでShift+Hを押すと、スレッドの表示/非表示を切り替えることができます。Tasks: 23, 10 thrと表示される場合、それらが表示されていることを意味します。カーネルスレッド(kernel threads)もShift+Kで表示できます。それらが表示される場合、Tasks: 23, 40 kthrと表示されます。
プロセスID / PID
新しいプロセスが起動するたびに、