LinuxサーバのCPU使用率を見たい時にtopコマンドをよく使うが、使う上で気を付けないといけないのが、タイミングによっては表示されるCPU使用率がユーザの期待するものとは異なるということ。
サマリ情報のCPU行
topコマンドを実行するとCPUやメモリ使用率のサマリ情報がヘッダとして表示されるが、最初に表示されるCPU使用率はOSを起動してからの平均値なので、無風状態が長いほど低い数値が出る。
なお、vmstatで表示されるCPU使用率も同じ仕様なので、パフォーマンス調査などの際には最初の表示は見ない方がいい。
以下はvmstatのmanの一部
vmstat reports information about processes, memory, paging, block IO, traps, and cpu activity.
The first report produced gives averages since the last reboot.
%CPU列の仕様
manでtopコマンドを引くとカラムの説明として以下の記載がある。
k: %CPU -- CPU usage
The task's share of the elapsed CPU time since the last screen update, expressed as a percentage of total CPU time.
したがって、%CPU列は前回のスクリーン更新からのタスクのCPU時間占有率を表す。
前回topコマンドを実行してからCPU使用率がほぼ0%で、急激に100%近くになった状態でtopコマンドを実行しても、直後に表示されるCPU使用率は100%には遠く及ばないことになる。
実際に試してみる
超簡単なCPU負荷スクリプトを作った。見ての通り60秒スリープした後に無限ループする。
$ cat cpuload.pl
#!/usr/bin/perl
sleep 60;
while(1){
}
スクリプト実行後、topコマンドでCPU使用率を見てみる。
※サーバはAWSのt2.microなので1コア
$ ./cpuload.pl &
[1] 4801
$
$ top -p 4801 -d 60 -b -n 2 ; top -p 4801 -b -n 1
top - 10:00:56 up 7:42, 2 users, load average: 0.02, 0.22, 0.19
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
Cpu(s): 4.0%us, 0.2%sy, 0.0%ni, 95.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1017324k total, 339368k used, 677956k free, 15868k buffers
Swap: 0k total, 0k used, 0k free, 252192k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4801 ec2-user 20 0 126m 3564 3248 S 0.0 0.4 0:00.00 cpuload.pl
top - 10:01:56 up 7:43, 2 users, load average: 0.16, 0.21, 0.18
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s): 17.6%us, 0.0%sy, 0.0%ni, 82.4%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1017324k total, 339864k used, 677460k free, 15880k buffers
Swap: 0k total, 0k used, 0k free, 252196k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4801 ec2-user 20 0 126m 3564 3248 R 17.5 0.4 0:10.53 cpuload.pl
top - 10:01:56 up 7:43, 2 users, load average: 0.16, 0.21, 0.18
Tasks: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
Cpu(s): 4.0%us, 0.2%sy, 0.0%ni, 95.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1017324k total, 339492k used, 677832k free, 15880k buffers
Swap: 0k total, 0k used, 0k free, 252196k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4801 ec2-user 20 0 126m 3564 3248 R 99.9 0.4 0:11.04 cpuload.pl
①スクリプト起動後、②"①"の60秒後、③"②"の直後 の計3回topコマンドを実行している。
ヘッダおよびスクリプトのCPU使用率を見てみると、
① ヘッダ:Cpu(s): 4.0%us, 0.2%sy, 0.0%ni, 95.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
スクリプト:0.0%
② ヘッダ:Cpu(s): 17.6%us, 0.0%sy, 0.0%ni, 82.4%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
スクリプト:17.5%
③ ヘッダ:Cpu(s): 4.0%us, 0.2%sy, 0.0%ni, 95.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
スクリプト:99.9%
となっている。
②でTIME+が10秒超であることから、本来はとっくにスクリプトのCPU使用率はほぼ100%のはずだが、①の時点からのCPU時間占有率なので17.5%と低い数値が出ている(sleepの間はCPUを使用していない)。
また、③はヘッダとスクリプトのCPU使用率が大きく乖離してしまっている。これは③で新しくtopコマンドを実行しており、OS起動時からの平均がヘッダに表示されているためで、①のヘッダとほぼ同じ数値になっている。
まとめ
仕様を理解して表示に惑わされない。
CPUのパフォーマンスを見たい時はtopコマンドを流しっぱなしにして2回目以降の表示を見る(vmstatも同じ)。
ちなみに上の試してみたでやっているが、topコマンドは"-b"でバッチモード、"-d"で更新間隔(秒)、"-n"で更新回数の指定ができる。バッチモードの何が嬉しいかって、ログにtopコマンドのスクリーン更新ごとの表示がきちんと残ること。例えば「webサーバ#1~#3があるけど#1だけなぜかCPU使用率が高い」なんて時に
# top -b -d 3 -n 100
と各サーバで実行して、ログで各プロセスを比較してみるのに役立つ。