[AWS] Ubuntu EC2インスタンスに意図的に負荷をかけ、CloudWatchでメトリクスを確認する

検証などのため、意図的にEC2インスタンスに負荷をかけたい場合があります。今回は、Ubuntuインスタンスで試す機会がありましたので、手順をまとめておきます。[前回の記事(メモリ使用率をCloudWatchに連携)](https://qiita.com/VA_nakatsu/items/2012bb3038d468005fe2) はこれをまとめるための長い前振りでした．．．

# CPU

stress-ngコマンド、あるいはopensslコマンドで負荷をかけることが可能です。

インストール手順：

```
$ sudo apt-get update
$ sudo apt install stress-ng
$ sudo apt install openssl
```

stress-ngコマンドの実行オプション：

```
$ stress-ng --cpu <vCPU数> -l <CPU使用率> -t <実行時間>

CPU負荷をかける場合
・-cpu： CPUの負荷試験を行う場合に指定する。CPUのコア数を指定する。
・-l： CPUの使用率を指定する。指定した数字(%)の負荷がかけられる。
・-t： 実行時間を指定する。
      数字のみの場合は秒数指定、数字の後に m, h, dを付けると分、時間、日の指定となる。
```

例として、t3a.mediumインスタンス(vCPU数2)でコマンド実行した結果は以下のようになります。指定した90%まで使用率が上昇していることが確認できます。

```
$ stress-ng --cpu 2 -l 90 -t 15m
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/f5f8c40a-90d3-e82c-5842-861ad3a0ce63.png)

他にはopensslコマンドを使う方法もあります。本来アルゴリズム速度を計測するものですが、CPUを100%使うため負荷テスト代わりに使うことができます。

```
$ openssl speed -multi <vCPU数>
```

t3a.mediumインスタンスで試したところ25分ほど使用率が100%になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/657cafcd-1a72-65d6-e57b-c9e444f624db.png)

# メモリ

メモリもstress-ngコマンドで負荷をかけることが可能です。CloudWatchで確認するためには事前に [前回記事の手順](https://qiita.com/VA_nakatsu/items/2012bb3038d468005fe2) でエージェントの設定をしておきます。

```
$ stress-ng -m <ワーカー数> --vm-bytes <メモリ消費量> -t <実行時間>

メモリ負荷をかける場合
・-m： 負荷をかけるワーカー数。急激にかけるのでなければ1を指定するとよい。
・--vm-bytes： 
      メモリ消費量を指定する。数字の後に単位を付けて
      b(バイト), k(キロバイト), m(メガバイト), g(ギガバイト), %(割合)での指定が可能。
      ワーカー数を増やした場合、この指定 × ワーカー数の負荷がかかるので注意。
・-t： 実行時間を指定する。
      数字のみの場合は秒数指定、数字の後に m, h, dを付けると分、時間、日の指定となる。
```

t3a.mediumインスタンス(メモリ4GiB)で試した結果です。

```
$ stress-ng -m 1 --vm-bytes 3072M --timeout 600
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/0c6f85ca-17fa-b163-1e50-bbb87aae505e.png)

メモリは100%指定しても、CloudWatch上は100%まで記録されることはありませんでした。ぎりぎりをテストするならバイト指定で調整する必要がありそうです。

```
$ stress-ng -m 1 --vm-bytes 100% --timeout 1200
stress-ng: info:  [9730] dispatching hogs: 1 vm
stress-ng: info:  [9730] successful run completed in 1200.02s (20 mins, 0.02 secs)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/c211ee9e-a351-b353-32f1-d596d4acc60f.png)

ワーカー数が1であれば、実メモリ量以上を指定した場合はエラーになります。あまりインスタンスサイズより大きな負荷をかけると異常の原因になる （ マニュアルに記載あり： `Note that this can cause systems to trip the kernel OOM killer on Linux systems if not enough physical memory and swap is not available.` ) ので注意して下さい。

```
$ stress-ng -m 1 --vm-bytes 3889M --timeout 120
stress-ng: info:  [9215] dispatching hogs: 1 vm
stress-ng: error: [9233] stress-ng-vm: gave up trying to mmap, no available memory
stress-ng: info:  [9215] successful run completed in 10.01s
```

# ディスク

ディスクもstress-ngコマンドが対応しています。

```
$ stress-ng -d <ワーカー数> --hdd-bytes <ディスク使用量> -t <実行時間> --temp-path <作業ディレクトリ>

ディスク負荷をかける場合
・-m： 負荷をかけるワーカー数。急激にかけるのでなければ1を指定するとよい。
・--vm-bytes： 
      メモリ消費量を指定する。数字の後に単位を付けて
      b(バイト), k(キロバイト), m(メガバイト), g(ギガバイト), %(割合)での指定が可能。
      ワーカー数を増やした場合、この指定 × ワーカー数の負荷がかかるので注意。
・-t： 実行時間を指定する。
      数字のみの場合は秒数指定、数字の後に m, h, dを付けると分、時間、日の指定となる。
・--temp-path： 一時ファイルを作成するディレクトリ
      指定しない場合は現在の作業ディレクトリが消費されます。
```

同じインスタンスで試したところ disk_io, disk_writeは上昇しましたが、disk_readは上昇が少なめでした。

```
$ stress-ng -d 1 --hdd-bytes 2048M -t 1200 --temp-path /tmp
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/7a8cc166-4a4e-eee1-5364-a3dfe66f52ef.png)

ディスク使用率を見ると、一時ファイルを作成して削除しているような様子が伺えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/7f238058-c9a8-8158-56f5-14e98090d67a.png)


# ネットワーク

ネットワークはstress-ngコマンドが対応していないため、今回はS3に同じファイルのPUTとGETを繰り返すスクリプトを作成して試しました。

```
※ダミーの1GBファイルを作成
$ dd if=/dev/zero of=1G.dummy bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 2.81233 s, 373 MB/s

$ ls -la 1G.dummy
-rw-r--r-- 1 ubuntu ubuntu 1048576000 Nov 16 02:59 1G.dummy

※指定した回数繰り返すシェルスクリプト
$ cat stress_test.sh
#!/bin/bash
cnt=1
while [ $cnt -le $1 ]; do
    aws s3 cp 1G.dummy s3://<バケット名>/1G.dummy
    aws s3 cp s3://<バケット名>/1G.dummy .
    cnt=`expr $cnt + 1`
done

$ ./stress_test.sh 10
upload: ./1G.dummy to s3://<バケット名>/1G.dummy
download: s3://<バケット名>/1G.dummy to ./1G.dummy
Completed 265.2 MiB/1000.0 MiB (86.6 MiB/s) with 1 file(s) remaining
※以下省略※
```

これを実行すると NetworkIn, NetworkOutが上昇していることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/0ef50886-92b7-c245-85c4-d887ebd464a4.png)

この時のディスクIOです。右半分が今回のスクリプトによるもので、stress-ngの方が負荷かけられているのが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172826/f1575e0c-8868-97f8-8422-5397720b0eff.png)

以上です。今回は負荷といってもストレステストほどの負荷ではなく、メトリクスの上限まで負荷を上げる程度の確認でしたが、CloudWatchメトリクスをそれぞれ上昇させられることが確認できました。

# 参考資料

- [Ubuntu Manpage: stress-ng - a tool to load and stress a computer system](https://manpages.ubuntu.com/manpages/artful/man1/stress-ng.1.html)