Linuxパフォーマンス調査などで使うコマンドメモ

パフォーマンスなどの調査をする時に利用する便利コマンドメモ。
これないぞ、あれないぞなどあると思いますがとりあえず本などを参考にまとめたものをピックアップしています。

# 参考

+ [[24時間365日] サーバ/インフラを支える技術 ‾スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)](http://www.amazon.co.jp/24%E6%99%82%E9%96%93365%E6%97%A5-%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-%E2%80%BE%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%A9%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3%E3%80%81%E3%83%8F%E3%82%A4%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E3%80%81%E7%9C%81%E5%8A%9B%E9%81%8B%E7%94%A8-PRESS-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4774135666/ref=sr_1_3?ie=UTF8&qid=1462194522&sr=8-3&keywords=%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E3%82%92)
+ [絵で見てわかるシステムパフォーマンスの仕組み](http://www.amazon.co.jp/%E7%B5%B5%E3%81%A7%E8%A6%8B%E3%81%A6%E3%82%8F%E3%81%8B%E3%82%8B%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF-%E5%B0%8F%E7%94%B0-%E5%9C%AD%E4%BA%8C/dp/4798134600/ref=sr_1_1?ie=UTF8&qid=1462194568&sr=8-1&keywords=%E7%B5%B5%E3%81%A7%E8%A6%8B%E3%81%A6%E3%82%8F%E3%81%8B%E3%82%8B%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF)

# CPU使用率やメモリなど全体の概要把握

## top

デフォルトでは3秒ごとにOSで利用しているプロセスの数や状態、またOS全体のシステムリソース状況が分かります。

パフォーマンスが悪い場合にOS全体としてどのリソースの利用が多いのか(CPU負荷なのかメモリ利用率が高いのか)などの判断に有用だと思われます。

```bash
top - 22:36:56 up 28 min,  2 users,  load average: 0.00, 0.02, 0.05
Tasks:  77 total,   1 running,  76 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1019344k total,  1006192k used,    13152k free,    21868k buffers
Swap:        0k total,        0k used,        0k free,   461612k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 7499 mysql     20   0 1040m 448m  14m S  0.3 45.1   0:00.44 mysqld
    1 root      20   0 19636 2516 2196 S  0.0  0.2   0:00.85 init
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd
    3 root      20   0     0    0    0 S  0.0  0.0   0:00.04 ksoftirqd/0
    4 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kworker/0:0
    5 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/0:0H
    7 root      20   0     0    0    0 S  0.0  0.0   0:00.05 rcu_sched
    8 root      20   0     0    0    0 S  0.0  0.0   0:00.00 rcu_bh
    9 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0
   10 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kdevtmpfs
   11 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 netns
   12 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 perf
```

%CPUがCPU使用率、%MEMがメモリ利用率なのでこの値が異常に高いプロセスがあれば、そのプロセスがリソースを消費しパフォーマンスに影響を及ぼしている可能性があります。

また、左から7番目の「S」と書かれた列はプロセスの状態を示します。

+ R->Running(実行状態もしくは実行可能状態)
+ S->Sleeping(スリープ状態。ネットワークを介したデータ送受信の際もこのステータス)
+ D->Uninterruptible sleep(IO待ち)

上記のプロセス状態を確認し、Dの状態が続いてるプロセスがあればIO待ちによってパフォーマンス遅延が発生している可能性があります。

デフォルトではCPU使用率でソートされて表示されますが、コマンドをオプションを指定することで他のフィールドでソートして表示する事もできます。

```bash
# CPU使用率でソート
$top 

# メモリ使用率でソート
$top -a
```

## vmstat

メモリやCPU使用率を確認できます。

```bash
$vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0  14364  22304 459732    0    0    13   106   16   45  0  0 99  0
```

cpu項の「id」列ではアイドル(空いている)割合をパーセントで表示し、「wa」列ではストレージのIO完了待ちを示します。

上記によってシステム全体でのCPU負荷であったり、IO待ちが発生してないかなど確認できます。

マルチコア環境の場合、CPU使用率は全体のコアでの平均なのでいずれかのコアにCPU負荷が掛かっているかなどは別途`mpstat`や後述する`sar`で確認できます(sysstatパッケージのインストールが必要)

```bash
$mpstat -P ALL
Linux 4.4.5-15.26.amzn1.x86_64 (ip-172-31-20-16) 	2016年05月01日 	_x86_64	(1 CPU)

00時37分38秒  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
00時37分38秒  all    0.39    0.00    0.07    0.30    0.00    0.00    0.06    0.00   99.17
00時37分38秒    0    0.39    0.00    0.07    0.30    0.00    0.00    0.06    0.00   99.17

```

## ps

現在利用しているプロセス・ストッドごとのCPUやメモリ使用率が分かります。
上記よりどのプロセス・ストッドが問題となっているかを特定するために利用できます。

以下参考の表示出力を記載します。

```bash
$ps aux |egrep 'PID|apache'|grep -v 'grep'
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
apache   27935  0.0  0.5 178544  5924 ?        S    11:46   0:00 /usr/sbin/httpd
apache   27936  0.0  0.5 178544  5924 ?        S    11:46   0:00 /usr/sbin/httpd
apache   27937  0.0  0.5 178544  5924 ?        S    11:46   0:00 /usr/sbin/httpd
apache   27938  0.0  0.5 178544  5924 ?        S    11:46   0:00 /usr/sbin/httpd
apache   27939  0.0  0.5 178544  5924 ?        S    11:46   0:00 /usr/sbin/httpd
apache   27940  0.0  0.5 178544  5924 ?        S    11:46   0:00 /usr/sbin/httpd
apache   27941  0.0  0.5 178544  5924 ?        S    11:46   0:00 /usr/sbin/httpd
apache   27942  0.0  0.5 178544  5924 ?        S    11:46   0:00 /usr/sbin/http
```

以前記事を書いたので詳細はこちらを参照下さい。

[psコマンドで表示される内容について調べた](http://qiita.com/toshihirock/items/565fe71d778d3ee36b96)

## sar

`vnstat`とコマンドと同じくsysctlパッケージのインストールが必要ですが、`sar`コマンドでもOSリソースの状態を確認できます。

sarコマンドの便利な点として今までのコマンドは現在のリソース状態を表示するものでしたが、sarコマンドでは過去のタイミングのリソース状態も確認することができます。

```bash
$sar
Linux 4.4.5-15.26.amzn1.x86_64 (ip-172-31-20-16)        2016年05月01日  _x86_64_        (1 CPU)

00時40分01秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
00時50分01秒     all      0.01      0.00      0.00      0.00      0.00     99.99
01時00分01秒     all      0.01      0.00      0.01      0.00      0.00     99.98
01時10分01秒     all      0.00      0.00      0.01      0.00      0.01     99.98
01時20分01秒     all      0.01      0.00      0.01      0.00      0.00     99.99
01時30分01秒     all      0.00      0.00      0.00      0.00      0.00     99.99
01時40分01秒     all      0.00      0.00      0.00      0.00      0.00     99.99
01時50分01秒     all      0.00      0.00      0.00      0.00      0.00     99.99
02時00分01秒     all      0.00      0.00      0.00      0.00      0.00     99.99
02時10分01秒     all      0.01      0.00      0.00      0.00      0.00     99.99
02時20分01秒     all      0.01      0.00      0.00      0.00      0.00     99.98
02時30分01秒     all      0.00      0.00      0.00      0.00      0.00    100.0
```

上記のように過去に遡ってCPU使用率やIO待ちの状態などが確認できます。

また、マルチコアCPUの場合にそれぞれのコアの状況も確認できます。
(以下の環境はコアは一つのみですが。。)

```bash
$sar -P ALL
Linux 4.4.5-15.26.amzn1.x86_64 (ip-172-31-20-16) 	2016年05月02日 	_x86_64	(1 CPU)

00時00分01秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
00時10分01秒     all      0.00      0.00      0.01      0.00      0.00     99.99
00時10分01秒       0      0.00      0.00      0.01      0.00      0.00     99.99

00時10分01秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
00時20分01秒     all      0.00      0.00      0.00      0.00      0.00     99.99
00時20分01秒       0      0.00      0.00      0.00      0.00      0.00     99.99

00時20分01秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
00時30分01秒     all      0.00      0.00      0.00      0.00      0.00     99.99
00時30分01秒       0      0.00      0.00      0.00      0.00      0.00     99.99

00時30分01秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
00時40分01秒     all      0.01      0.00      0.00      0.00      0.00     99.99
00時40分01秒       0      0.01      0.00      0.00      0.00      0.00     99.99
```

オプション指定により、メモリの情報も確認できます。

```bash
$sar -r
Linux 4.4.5-15.26.amzn1.x86_64 (ip-172-31-20-16) 	2016年05月02日 	_x86_64	(1 CPU)

00時00分01秒 kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit
00時10分01秒    408128    611216     59.96     34004    492920     61708      6.05
00時20分01秒    408020    611324     59.97     34028    492924     61708      6.05
00時30分01秒    408108    611236     59.96     34056    492920     61708      6.05
00時40分01秒    407968    611376     59.98     34088    492928     61708      6.05
```

# メモリ

## free

メモリに特化して詳細を表示したい場合には`free`コマンドを利用します。

```bash
$free
             total       used       free     shared    buffers     cached
Mem:       1019344     555556     463788         68      27192     447704
-/+ buffers/cache:      80660     938684
Swap:            0          0          0
```

表示される項目の詳細については以下の記事が分かりやすかったです。

[減り続けるメモリ残量！ 果たしてその原因は!? (2/3)](http://www.atmarkit.co.jp/ait/articles/0810/01/news134_2.html)


上記にも書いてあるのですが、Mem行のfree列の値は **何の用途にも使っていない物理メモリ量** と書いてある点が注意です。

CPUはストレージとのデータを直接読み込むことができず、一度メモリにロードする必要があります。(ページキャッシュ)
ページキャッシュでは新しくストレージデータの読み書き要求があってメモリが必要とならない限り、メモリを開放しません。ということはシステムが稼働している限り、基本的にどんどんページキャッシュが溜まっていくのでfree列の値はどんどん減っていくことが予想されます。

じゃあどうやって利用可能なメモリ量を算出できるかというと上記freeコマンドの値を算出するために利用する`/proc/meminfo`の値を利用します。

上記ファイルに **Active,Inactive** という値があります。
Activeはまだストレージと同期が取れていない捨てられないページキャッシュ、Inactiveは既にストレージと同期済みの捨てられるページキャッシュとなります。

上記より

+ freeコマンドで表示されるMem行のfree列の値+Inactiveの値

ということが言えます。

```bash
$cat /proc/meminfo |egrep -e "Active:|Inactive:|MemFree:"
MemFree:          463812 kB
Active:           265940 kB
Inactive:         224792 kB
```

先ほどのfreeの結果も踏まえた内容は以下になります。

+ メモリ総量(freeコマンド1行目のtotal列)-> 1019344KB
+ ページキャッシュを含めず、利用してるメモリ(freeコマンド2行目のused列)->80660KB
+ ページキャッシュを含めた場合の空き容量(freeコマンド2行目のfree列)->938684KB
+ 利用できるメモリ量(MemFree+Inactive)->688604KB

# ストレージ

## iostat

`iostat`コマンドを使うことでブロックデバイスごとの負荷状況が確認できます。

```bash
# 利用できるブロックデバイスを確認
$lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0   8G  0 disk
└─xvda1 202:1    0   8G  0 part /

# 負荷を確認
$iostat -x
Linux 4.4.5-15.26.amzn1.x86_64 (ip-172-31-20-16) 	2016年05月01日 	_x86_64	(1 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.09    0.01    0.03    0.08    0.01   99.78

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
xvda              0.00     0.27    0.31    0.45     7.15    44.71    68.67     0.01    7.08   1.16   0.09
```

r/s列が秒間あたりの読み込み、w/s列は秒間あたりの書き込み数(IOPS)を示しています。

試しにストレージの性能評価に使える`fio`コマンドを使って書き込みの負荷をかけてみます。

```bash
# 書き込みを連続で行う
$fio -filename=/tmp/test2g -direct=1 -rw=write -bs=4k -size=2G -numjobs=64 -runtime=10 -group_reporting -name=file1

# iostatによる確認を1秒ごとに出力
$iostat -x 1 > ioResult.txt

# 確認
$cat ioResult.txt

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.00    0.00    1.01   48.48    1.01   49.49

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
xvda              0.00     0.00    0.00  812.12     0.00  6496.97     8.00     0.50    0.62   0.61  49.70
```

連続書き込みを行っているのでw/sの値と%iowaitの値も上がりました。
上記ようにストレージに負荷を加えた際に状況を確認することができます。

# ネットワーク

## vnstat

[vnstat を使ってlinuxサーバのtrafficをお手軽に確認する](http://hogem.hatenablog.com/entry/20120809/1344518298)

環境によってはパッケージのインストールが必要ですが、`vnstat`コマンドによってネットワークトラフィック状態を確認することができます。

インストールは以下のように実行(AmazonLinuxの場合)

```bash
$sudo yum install --enablerepo=epel vnstat -y
```

-lオプションを指定する事で現在の通信状況をリアルタイムで見ることができます。

```bash
$vnstat -i eth0 -l
Monitoring eth0...    (press CTRL-C to stop)

   rx:        0 kbit/s     0 p/s          tx:        4 kbit/s     0 p/s
   

# Ctrl+Cで停止
```

なお、RXは受信パケット数、TXは送信パケットを意味します。
上記によってトラフィック量を確認し、帯域が不足していないかなどを確認することができます。

## tcpdump

トラフィックの詳細な内容を確認することができます。
トラフィックが多い場合に詳細などのようなトラフィックが多いのかなどの調査に利用することができるかと思います。

以前詳細は記事を書きました。

[Wiresharkを使ってHTTPリクエストを見てみた](http://qiita.com/toshihirock/items/49753320e4582f650987)