Linux負荷監視コマンドまとめ

できるだけAmazon Linuxに標準で入っているもの、パッケージマネージャでインストールできるものでまかないたいと思っています。
メジャーでないものも含めて、便利なツールを探している場合はこちら：
[Linuxのモニタリングツール80個](https://blog.serverdensity.com/80-linux-monitoring-tools-know/)

##負荷監視コマンド一覧
コマンド | 用途 | 収録パッケージ
----|------|------
vmstat 2 | システム全体の負荷を見るならこれ。2で2秒ごと | procps
top | CPUやメモリを食っているプロセスを特定したいならこれ | procps
sar | 過去の負荷の履歴をみたいならこれ | sysstat
mpstat -P ALL 1 | CPUコアごとの負荷を見るならこれ | sysstat
dstat -taf | 標準ではインストールされていないが、一番便利なコマンド | dstat
free -m | メモリ。-mでメガバイト単位 | procps
iostat -dmxt 1 | IO状況 | sysstat

※収録パッケージ名はAmazon Linuxの場合
procpsは数年間動きがなかったのでprocps-ngというプロジェクトがフォークした。ディストリビューションによってはprocps-ngが入っているかもしれない。

## 最低限覚えるべきはvmstat

vmstatは多くの環境で標準でインストールされており、表示項目もメモリ・スワップ・IO・CPUと一通りそろっている。

`vmstat 2`で2秒ごとに表示される。
`-t`をつけると時刻も表示される。

```console
$ vmstat -t 2
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ ---timestamp---
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  1      0 258812 469164 174728    0    0    65     1    8   11  0  0 100  0  0       2015-12-19 00:00:54 JST
 1  1      0 239352 484316 174736    0    0  7576     0 2141 60936 13 17  0 70  1       2015-12-19 00:00:56 JST
 2  0      0 219420 499808 174728    0    0  7746     0 2189 59653 12 17  0 70  1       2015-12-19 00:00:58 JST
 1  0      0 195316 512228 174696    0    0  6210     0 1804 76138 16 20  0 63  1       2015-12-19 00:01:00 JST
 0  0      0 184096 520212 174724    0    0  3992     0 1205 39586  8  8  0 56 27       2015-12-19 00:01:02 JST
```

項目名 | 意味
-------|-----
r | 「実行中または実行待ち」（runnable）のプロセス数
b | uninteruptibleなIO待ちのプロセス数（r+bがロードアベレージに等しい）
swpd | スワップされたメモリ
free | 空きメモリ。これは小さくてもよい。free+buff+cacheが少なければ問題
buff | バッファキャッシュ
cache | ページキャッシュ
si | スワップイン
so | スワップアウト
bi | ブロックデバイスからの読み込み
bo | ブロックデバイスへの書き込み
in | 1秒間の割り込み回数（タイマー含む）
cs | 1秒間のコンテキストスイッチ回数
us | ユーザーCPU時間（カーネル以外が使用したCPU使用率）
sy | システムCPU時間（カーネルが使用したCPU使用率）
id | アイドル時間
wa | IO待ち時間
st | 仮想マシンに盗まれた時間

メモリの単位はK（キロバイト）。`--unit M`でメガバイト単位に変更できる。

今のカーネルでは1ブロックは1024バイト。
> All linux blocks are currently 1024 bytes.  Old kernels may report blocks as 512 bytes, 2048 bytes, or 4096 bytes.

### バッファキャッシュとページキャッシュの違い

ページキャッシュはページ（ファイルの一部。4KB単位）をキャッシュするためのもの。
バッファキャッシュはディスク上のブロックをキャッシュするためのもの。ディスク上のブロックの大半はファイルの中身を保持しているが、メタデータのブロックもある。そういったブロックはバッファキャッシュには入るがページキャッシュには入らない。

歴史的にはバッファキャッシュの方が古い。大昔のUnixにはバッファキャッシュしかなかった。後からページキャッシュが導入されたが、それを行った人々はバッファキャッシュには手を付けようとしなかった。Linux 2.4からこの2つは統合された。


## dstat

`dstat`はCentOSやAmazon Linuxなら`yum`でインストールできる。非標準だが比較的広く使われていると思う。
CPU負荷をコアごと、IO負荷をディスクごと、ネットワーク転送量をインターフェイスごとに表示できる。

```console
$ dstat -taf
----system---- -------cpu0-usage------ --dsk/xvda----dsk/xvdf- --net/eth0- ---paging-- ---system--
  date/time   |usr sys idl wai hiq siq| read  writ: read  writ| recv  send|  in   out | int   csw 
19-12 00:01:50|  0   0 100   0   0   0|  65k  827B:  34B   52B|   0     0 |   0     0 |   8    18 
19-12 00:01:51|  0   0 100   0   0   0|   0     0 :   0     0 |  92B 1990B|   0     0 |  16    28 
19-12 00:01:52|  0   0 100   0   0   0|   0     0 :   0     0 |  40B  500B|   0     0 |  11    18 
19-12 00:01:53|  0   0 100   0   0   0|   0     0 :   0     0 |  40B  500B|   0     0 |  11    18 
19-12 00:01:54|  1   0  99   0   0   0|   0     0 :   0     0 |  40B  500B|   0     0 |  11    18 
19-12 00:01:55|  0   0 100   0   0   0|   0     0 :   0     0 |  40B  516B|   0     0 |  11    18 
```

CPUをcpu0, cpu1だけに絞り込みたいときは

```
dstat -taf -C 0,1
```

ディスクをxvda,xvdfだけに絞り込みたいときは

```
dstat -taf -D xvda,xvdf
```

## top

`htop`や`glance`など、`top`より使いやすい非標準コマンドは多数ある。しかし標準でインストールされているものに慣れておくという意味では`top`を使った方がいいかもしれない。
…ただ、`top`もバージョンによって操作方法が異なるのが悩ましい。

### 操作方法（procps-3.2.8 / Amazon Linuxの場合）
キー | 操作 |
---|---
? | ヘルプを表示
f | 表示カラム選択 
z | カラー表示
< > | ソートカラムを変更（左右に変わっていく）。現在のソートカラムを判別しやすくするには bx とタイプするとよい
b | ハイライトのbold/reverseをトグル
x | 現在のソートカラムをハイライト
R | ソートの昇順・降順を逆に
k | プロセスをkill。シグナル番号は15（killコマンドのデフォルト）、9（強制終了）
r | NICE値を変更。上げる事で優先度を下げられる。

### 操作方法（procps-ng 3.3.12 / Arch Linuxの場合）
キー | 操作 | 
---|---
? | ヘルプを表示
f | スペースで表示カラムトグル。sでソートカラム選択
R | ソートの昇順・降順を逆に
o | フィルター追加。「COMMAND=httpd」のように入力
= | フィルターをクリア
k | プロセスをkill。シグナル番号は15（killコマンドのデフォルト）、9（強制終了）
r | NICE値を変更。上げる事で優先度を下げられる。

### VIRTはmalloc()しただけで増える。RESは増えない

`malloc()`したメモリに書き込むと初めてRESは増える

### PR（優先度）とNI（nice値）は低いほど優先される
ややこしいが、なぜこうなっているかはっきりしたことは不明。
日常会話でも「これは優先順位1位だ」「第一優先」と言う場合は低いほうが優先なので、それと同じなのか。
http://stackoverflow.com/questions/14067128/why-are-niceness-values-inversely-related-to-process-priority


## ps

`ps`はオプション指定がBSD系（ハイフンなし。`ps aux`など）とSystem V系（ハイフンあり。`ps -ef`など）の2通りあってややこしい。

ひとまず`ps auxf`か`ps -efH`だけ覚えておけばいいと思う（`f`と`-H`はどちらもプロセスの親子関係をツリー表示するオプション）。

スレッドも表示したい場合は`ps -efL`。

```console
# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         2  0.0  0.0      0     0 ?        S    Dec13   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    Dec13   0:07  \_ [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   Dec13   0:00  \_ [kworker/0:0H]
```

```console
# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         2     0  0 Dec13 ?        00:00:00 [kthreadd]
root         3     2  0 Dec13 ?        00:00:07   [ksoftirqd/0]
root         5     2  0 Dec13 ?        00:00:00   [kworker/0:0H]
```

`[kthreadd]`のように`[]`で囲まれて表示されるプロセスはカーネルスレッド。
argv[0]を空にすることでこの表示にできると聞いて試してみたが、↓ではダメだった。

```c
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    execl("/usr/bin/sleep", "", "5", NULL);
    return 0;
}
```

参考：Linux - psコマンドまとめ - Qiita
http://qiita.com/shell/items/68ed71a7f018e5688f73


## ページングとスワッピングの違い

* スワッピングとはプロセス丸ごとディスクに追い出すこと
* ページングとはページ（4KB）単位で追い出すこと

>Linuxカーネルではページを二次記憶に追い出すことをスワップと呼んでいますが、伝統UNIXで行っているプロセスイメージ全体を追い出すスワップアウトではなく、ページ単位で追い出すページアウトのことを指しています。Linuxでは伝統UNIXのスワップアウト機能に相当する機構は実装されていません。
>http://osdn.jp/projects/linux-kernel-docs/wiki/0.6%E3%80%80%E3%83%A1%E3%83%A2%E3%83%AA%E7%AE%A1%E7%90%86

# 参考

6万ミリ秒でできるLinuxパフォーマンス分析 | Yakst
https://yakst.com/ja/posts/3601?platform=hootsuite

Linuxモニタリングツール80個
https://blog.serverdensity.com/80-linux-monitoring-tools-know/