sarコマンドの使い方

# 概要

サーバの応答が遅くなるなど計算機のパフォーマンスに問題が生じたとき、原因としてCPU・メモリ・IO・ネットワークなど色々な原因が考えられます。原因を特定するために、それぞれのリソースの状況を見ていき、例えば「CPU使用率が100%近い値になっていないか」「メモリが足りなくなってスワッピングが頻繁に起きていないか」など考えられるものを検証していく必要があります。

計算機の状況を知るためのコマンドには`vmstat`や`iostat`、`top`や`ps`などいろいろあると思いますが、その中でも`sar`は様々なリソースについて過去に遡って見ることができるため、大まかな原因特定に非常に役立つので、使い方についてまとめておきます。

# `sar`コマンドの基本的な使い方

#### オプション/引数

`sar`を使えば、CPU・メモリなど計算機のパフォーマンスに関わる様々なリソースの情報を得ることができます。引数やオプションの基本的な構造は以下の通り。

```
sar [...options] <interval> <count> -f <saXX file>
```

ここで、`[...options]`には、「どのCPUリソースについて見たいか」を指定します。例えば、`-r`というオプションならばメモリの情報を、`-u`ならばCPUの情報を見ることができるという感じです。一方で、そのあとの`<interval>`や`<count>`などの引数は、あるリソースについて、「いつの情報をどのような間隔」で見るのかを指定します。

この記事では、どういうオプションを指定した時にどのような情報が得られるのかを主にまとめますが、その前に「いつの情報を見るか」を指定する引数について簡単に見ておきます。以下の例では、一貫して`-r`オプションでメモリの情報を見ることにします。

#### 引数なし

オプション以外の引数を指定せず（例えば`sar -r`）とコマンドを打つと、システムが自動で一定間隔で取ってくれているその日のリソースの情報が出力されます。間隔は自分で指定することもできますが、デフォルトでは10分になっていることが多いと思います。

```shell
$ sar -r
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

12:00:01 AM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
12:10:01 AM    416372    599052     59.00     24524    434468    276164      8.87    371660    157708         0
12:20:02 AM    416544    598880     58.98     24568    434480    276164      8.87    371644    157756         0
12:30:01 AM    414176    601248     59.21     24668    434540    303108      9.74    373848    157596         0
12:40:01 AM    416288    599136     59.00     24716    434536    275948      8.87    371800    157632         0
12:50:01 AM    415956    599468     59.04     24780    434540    275948      8.87    371860    157688         0
01:00:01 AM    415772    599652     59.05     24984    434624    276052      8.87    373380    156556         4
01:10:01 AM    415680    599744     59.06     25052    434628    276052      8.87    373416    156600         0
...
```

#### `saXX`ファイルの指定

引数なしだと当日の情報しか見れないが、過去に遡って昨日以前の情報を見たいときがあります。実は、システムが`sar`コマンドで自動で取得された情報は、一定期間はファイルとして特定のディレクトリに保存されています。例えば、CentOS7だと`/var/log/sa`以下にありました。

```shell
$ ls /var/log/sa
sa01  sa12  sa15  sa18  sa21  sa24  sa27  sa30   sar13  sar16  sar19  sar22  sar25  sar28
sa10  sa13  sa16  sa19  sa22  sa25  sa28  sar11  sar14  sar17  sar20  sar23  sar26  sar29
sa11  sa14  sa17  sa20  sa23  sa26  sa29  sar12  sar15  sar18  sar21  sar24  sar27  sar30
```

`sar`の後の数字が日付を表していて、例えば直近の26日の情報は`sa26`ファイルに保存されています。このファイルの名前を`-f`オプションの後に指定してあげると、その日の`sar`の結果を見ることができます。

```shell
$ sar -r -f /var/log/sa/sa26
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	09/26/2018 	_x86_64_	(2 CPU)

12:00:01 AM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
12:10:01 AM    359760    655664     64.57     91228    407732    336816     10.82    385472    190128         4
12:20:02 AM    359512    655912     64.59     91256    407740    336816     10.82    385492    190144         0
12:30:01 AM    359800    655624     64.57     91280    407752    336816     10.82    385484    190132         0
12:40:01 AM    359736    655688     64.57     91320    407768    336816     10.82    385516    190152        32
12:50:01 AM    359076    656348     64.64     91568    408048    336816     10.82    385916    190292         0
01:00:01 AM    359360    656064     64.61     91580    408040    336816     10.82    385988    190288         0
01:10:01 AM    359132    656292     64.63     91604    408064    336816     10.82    386040    190284         0
...
```

#### `interval`/`count`の指定

ここまでで、過去に遡って計算機のリソース情報が見れることがわかりました。しかし、リアルタイムでもっと細かく計算機の状況が見たいことがあるでしょう。そのときは、情報を取得する間隔（`interval`）と回数（`count`）を指定します。例えば、以下は１秒おきに３回情報を取得する例です。

```shell
$ sar -r 1 3
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

11:07:45 PM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
11:07:46 PM    351688    663736     65.37     50352    456532    287176      9.23    394068    182800         0
11:07:47 PM    351688    663736     65.37     50352    456532    287176      9.23    394108    182800         0
11:07:48 PM    351704    663720     65.36     50352    456532    287176      9.23    394120    182800         0
Average:       351693    663731     65.36     50352    456532    287176      9.23    394099    182800         0
```

`count`を引数として与えない場合は指定した`interval`で永遠に情報を取得し続けることになります。

```shell
$ sar -r 2
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

11:10:56 PM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
11:10:58 PM    351584    663840     65.38     50368    456536    287232      9.23    394124    182816         0
11:11:00 PM    351584    663840     65.38     50368    456536    287232      9.23    394124    182816         0
11:11:02 PM    351584    663840     65.38     50368    456536    287232      9.23    394128    182816         0
11:11:04 PM    351584    663840     65.38     50368    456536    287232      9.23    394128    182816         0
11:11:06 PM    351584    663840     65.38     50368    456536    287232      9.23    394128    182816         0
11:11:08 PM    351584    663840     65.38     50368    456536    287232      9.23    394128    182816         0
11:11:10 PM    351584    663840     65.38     50368    456536    287232      9.23    394128    182816         0
...
```

# 見るリソースを指定するオプション

ここまでで、`sar`コマンドを使って「いつの」情報を見るかの指定方法についてはだいたいわかったので、次に「どの」情報を見るかの指定方法を見ていきます。最初に述べたように、どのリソースの情報を見るかはオプションで指定します。オプションは大量にある（`man`で見てくれ）のですが、その中でも利用頻度が高そうなオプションについて示します。また、各オプションに対して出力される情報の中でも特に有用と思われるものについてのみ内容を示しています。

## CPU

#### CPU使用率（`sar -P ALL`）

```shell
$ sar -P ALL 1
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

01:17:35 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:17:36 AM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:17:36 AM       0      0.00      0.00      0.00      0.00      0.00    100.00
01:17:36 AM       1      0.00      0.00      0.00      0.00      0.00    100.00

01:17:36 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:17:37 AM     all      0.00      0.00      0.00      0.00      0.00    100.00
01:17:37 AM       0      0.00      0.00      0.00      0.00      0.00    100.00
01:17:37 AM       1      0.00      0.00      0.00      0.00      0.00    100.00
...
```
- `%user`：CPUがユーザモードにあった時間の割合
- `%system`：CPUがカーネルモードにあった時間の割合
- `%iowait`：CPUがIO待ちをしていた時間の割合
- `%idle`：CPUがアイドル状態にあった時間の割合

マルチコアの場合、上記の結果ようにCPUごとの使用率が見られます。当然ですが、全てのカラムの値を足すと100%になります。`%idle`の値が小さいとCPUの使用率が高いということになので、CPUがパフォーマンスのボトルネックになっている可能性があります。

#### ランキュー/load average（`sar -q`）

```shell
$ sar -q 1
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

01:17:09 AM   runq-sz  plist-sz   ldavg-1   ldavg-5  ldavg-15   blocked
01:17:10 AM         1       102      0.00      0.01      0.03         0
01:17:11 AM         1       102      0.00      0.01      0.03         0
...
```
- `runq-sz`：ランキューにあるタスク数
- `ldavg-<n>`：最近n分間のロードアベレージ

ランキューにあるタスク数は、「CPUが現在同時に実行しているタスク数」を表しています。一般に、ランキューにあるタスク数がCPUの数を超えると、CPUの数が足りておらずパフォーマンスが落ちている可能性があると言われています。ランキューのタスク数は計算機のパフォーマンスがおかしい時に必ず見るべき重要な指標です。ロードアベレージはランキューのタスク数の時間平均で、こちらも同様に重要です。過去１分間、５分間、１５分間の値が表示されているので、大まかに、負荷が上がってきているのか落ち着いてきているのか把握することができます。

ランキュー/ロードアベレージについてのもっとちゃんとした説明は世の中にたくさんあると思いますが、自分は[サーバ/インフラを支える技術](https://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)の4.1節が非常にわかりやすかったのでおすすめです。

## メモリ

#### メモリ使用率（`sar -r`）

```shell
$ sar -r 1
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

01:16:48 AM kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
01:16:49 AM    416672    598752     58.97     25092    434648    274480      8.82    373028    156644         0
01:16:50 AM    416672    598752     58.97     25092    434648    274480      8.82    373028    156644         0
...
```
- `kbmemfree`：空きメモリのkB数
- `kbmemused`：使用中メモリのkB数
- `%memused`：メモリ使用率
- `kbbuffers`：バッファとして使われているメモリのkB数
- `kbcached`：ページキャッシュとして使われているメモリのkB数

メモリが足りなくなると、メモリの一部をストレージに退避させるスワッピングが発生しパフォーマンスが大きく劣化することがあるので注意。ただし、`kbbuffers`と`kbcached`はカーネルがいつでも開放することができるキャッシュなので、たとえメモリ使用率が高かったとしても、この２つの値が大きい場合には問題にはなりません。ページキャッシュやスワップについてのわかりやすい記事として、例えば [いまさら聞けないLinuxとメモリの基礎＆vmstatの詳しい使い方](https://qiita.com/kunihirotanaka/items/70d43d48757aea79de2d) を読むと良いでしょう。

#### スワッピング（`sar -S`、`sar -W`）

```shell
$ sar -S 1
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

01:16:32 AM kbswpfree kbswpused  %swpused  kbswpcad   %swpcad
01:16:33 AM   2097148         0      0.00         0      0.00
01:16:34 AM   2097148         0      0.00         0      0.00
...
```
- `kbswpfree`：空いているスワップ領域のkB数
- `kbswpused`：使用中のスワップ領域のkB数
- `%swpused`：スワップ領域の使用率

`kbswapused`が0よりも大きい値ならばスワッピングが発生していることになります。

```shell
$ sar -W 1
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

01:16:14 AM  pswpin/s pswpout/s
01:16:15 AM      0.00      0.00
01:16:16 AM      0.00      0.00
...
```
- `pswpin/s`：１秒間あたりのスワップインされたページ数
- `pswpout/s`：１秒間あたりのスワップアウトされたページ数

特に、スワップアウトが連続で起きている場合はパフォーマンスに影響を与えている可能性が高いです。

## ディスクIO

#### 読み込み/書き込み量（`sar -d -p`）

```shell
$ sar -d -p 1
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

01:15:54 AM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
01:15:55 AM       vda      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
01:15:55 AM       sr1      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

01:15:55 AM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
01:15:56 AM       vda      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
01:15:56 AM       sr1      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
...
```
- `tps`：１秒間あたりのI/O転送回数
- `td_sec/s`：１秒間あたりに読み込みを行ったセクター数
- `wr_sec/s`：１秒間あたりに書き込みを行ったセクター数
- `await`：I/O応答時間の平均
- `%util`：ディスクの使用率（I/O処理をしていてビジーだった時間の割合）

`%util`の値が大きい場合はIOがボトルネックになっている可能性があります。また、`await`はアプリケーションのパフォーマンスに直接的に影響する値なので重要です。

## ネットワーク

#### 受信/送信パケット数（`sar -n DEV`）

```shell
$ sar -n DEV 1
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

01:15:29 AM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
01:15:30 AM      eth0     19.00      0.00      2.27      0.00      0.00      0.00      0.00
01:15:30 AM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00

01:15:30 AM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
01:15:31 AM      eth0     23.00      1.00      2.39      0.18      0.00      0.00      0.00
01:15:31 AM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00
...
```
- `rxpck/s`：１秒間あたりの受信パケット数
- `txpck/s`：１秒間あたりの送信パケット数
- `rxkB/s`：１秒間あたりの受信kB数
- `txkB/s`：１秒間あたりの送信kB数

#### TCP接続数（`sar -n TCP`）

```shell
$ sar -n TCP 1
Linux 3.10.0-862.2.3.el7.x86_64 (118-27-1-88) 	10/01/2018 	_x86_64_	(2 CPU)

01:14:59 AM  active/s passive/s    iseg/s    oseg/s
01:15:00 AM      0.00      0.00      2.00      0.00
01:15:01 AM      0.00      0.00      1.00      1.00
...
```
- `active/s`：１秒間あたりのアクティブなTCP新規接続数
- `passive/s`：１秒間あたりのパッシブなTCP新規接続数
- `iseg/s`：１秒間あたりの受信セグメント数
- `oseg/s`：１秒間あたりの送信セグメント数

# まとめ

- `sar`を使うと、オプションを指定することによってCPUやメモリ、IOやネットワークなど計算機のパフォーマンスに関わる様々なリソースの情報を見ることができる。
- 自動で定期的に`sar`の情報が取得されているので、過去に遡って計算機の状況を確認することができる。一方で、リアルタイムで自由に間隔を指定して情報を取得することもできる