サーバのロードアベレージを分析した話【簡易版】

株式会社オズビジョンのユッコ (@terra_yucco) です。
幾度か記事に書いているように、オズビジョンでは監視ソフトとして Nagios を使っているのですが、一時期こいつが鳴って鳴ってうるさかったときがあります。

```
nagiosAPP [2:19 PM]
web08/Current LoadはWARNINGです:
WARNING - load average: 0.17, 5.54, 9.42
```

ただこういう風に表示はされるものの、対応する web サーバが表示しているサイトが重いということも特になく、かといって今までは発砲時に何かしらの問題が起きていることがあったので、止めていいのかどうかの判断がつかずにいました。

そんな風に悩んでいたらぱたりとでなくなったので、本当に負荷が落ち着いたのかを、とりあえずパッケージなど入れずに簡易計測してみたので、そのメモになります。

# サーバ負荷を分析
## 分析対象

Nagios アラート内容からも Load Average を見ることに。

## uptime

```terminal
$ uptime -V
procps version 3.2.8
```

## スクリプト群
### 出力の簡易保存

基本的にはずっと起動しっぱなしになるように作りました。
アラートを出している web08 は LB 配下に web01..08 までいるので 8 台に同じ内容を配りました。

```bash:uptime_trace.sh
#!/bin/bash -u
while [ 1 ]; do
  act_day=$( date +"%Y-%m-%d" )
  log_path=/tmp/${act_day}_uptime.log
  echo "${act_day}$(uptime)" >> /tmp/$(date +"%Y%m%d")_uptime.log
  sleep 1
done
```

### 落ちた時を考慮して cron に設定

こうしておけば何かでスクリプトが落ちても 5 分後には復帰できます。

```
*/5 * * * *     flock --timeout=0 /path/to/lock/get_uptime /path/to/script/uptime_trace.sh
```

## 取得できた結果

ごく普通に uptime の結果がほぼ 1s 間隔で並んだファイルを取得できました。
`/tmp` の下に置いたので、自動的に 7 日経てば消え、ディスクや i ノードもそんなに圧迫しませんでした。

```terminal
$ head -10 /tmp/20190616_uptime.log
2019-06-16 00:00:00 up 18 days,  8:16,  0 users,  load average: 0.16, 0.18, 0.12
2019-06-16 00:00:01 up 18 days,  8:16,  0 users,  load average: 0.16, 0.18, 0.12
2019-06-16 00:00:02 up 18 days,  8:17,  0 users,  load average: 0.16, 0.18, 0.12
2019-06-16 00:00:03 up 18 days,  8:17,  0 users,  load average: 0.16, 0.18, 0.12
2019-06-16 00:00:04 up 18 days,  8:17,  0 users,  load average: 0.15, 0.17, 0.12
2019-06-16 00:00:05 up 18 days,  8:17,  0 users,  load average: 0.15, 0.17, 0.12
2019-06-16 00:00:06 up 18 days,  8:17,  0 users,  load average: 0.15, 0.17, 0.12
2019-06-16 00:00:07 up 18 days,  8:17,  0 users,  load average: 0.15, 0.17, 0.12
2019-06-16 00:00:08 up 18 days,  8:17,  0 users,  load average: 0.15, 0.17, 0.12
2019-06-16 00:00:09 up 18 days,  8:17,  0 users,  load average: 0.14, 0.17, 0.11
```

## 分析
### 集計用スクリプト

awk はカンマがついても集計してくれたのが有能だと思う。
これも web01..08 に配りました。

```bash:sum.sh
#!/bin/bash -u
files="
/tmp/$( date -d "5 days ago" +%Y%m%d )_uptime.log
/tmp/$( date -d "4 days ago" +%Y%m%d )_uptime.log
/tmp/$( date -d "3 days ago" +%Y%m%d )_uptime.log
/tmp/$( date -d "2 days ago" +%Y%m%d )_uptime.log
/tmp/$( date -d "1 days ago" +%Y%m%d )_uptime.log
"
cat ${files} | awk -F ' ' 'BEGIN { sum = 0; i = 0 } { sum+= $11; i++ } END { print i; print sum / i }'
cat ${files} | awk -F ',' 'BEGIN { sum = 0; i = 0 } { sum+= $5; i++ } END { print sum / i }'
cat ${files} | awk -F ',' 'BEGIN { sum = 0; i = 0 } { sum+= $6; i++ } END { print sum / i }'
exit 0
```

### 踏み台からの集計ワンライナー

```terminal
for i in {1..8}; do host="web0${i}"; echo ${host}; ssh -i /path/to/key/secret.pem root@${host} "bash -u /path/to/script/sum.sh"; done
```

### 出力結果

```terminal
$ for i in {1..8}; do host="web0${i}"; echo ${host}; ssh -i /path/to/key/secret.pem root@${host} "bash -u /path/to/script/sum.sh"; done
web01
430527
0.108057
0.1047
0.0818376
web02
430691
0.106595
0.102893
0.0794985
web03
430664
0.106933
0.102868
0.0803043
web04
430685
0.106773
0.102199
0.0795081
web05
430683
0.0995264
0.0986996
0.0688978
web06
430738
0.10132
0.0961365
0.0755595
web07
430682
0.104807
0.100481
0.0775246
web08
430679
0.104834
0.100649
0.0801103
```

### 整形結果

どうして急におさまったのかはともかくとして、現状では web08 だけが特に重いとは言えなさそうなので、一度再発せずでインシデントを閉じる判断ができました。

ec2|data count|average 1m|average 5m|average 15m
:--|:--|:--|:--|:--
web01|430527|0.108057|0.1047|0.0818376
web02|430691|0.106595|0.102893|0.0794985
web03|430664|0.106933|0.102868|0.0803043
web04|430685|0.106773|0.102199|0.0795081
web05|430683|0.0995264|0.0986996|0.0688978
web06|430738|0.10132|0.0961365|0.0755595
web07|430682|0.104807|0.100481|0.0775246
web08|430679|0.104834|0.100649|0.0801103

## Conclusion

sar コマンドなどが使えなくても、簡易的な分析はできるので、困ったときにはぜひ使ってみてください。