PerformanceInsights試してみた(Amazon RDS for SQL Server)


今日はAWSのマネージドサービス、RDSの性能管理サービスであるPerformance Insightsを試してみます。
なんかぱっとググってみたんですが、あんまり資料なかったので、使用感や注意点について自分なりのまとめです。

# 概要

まずはそれぞれの登場人物についての概要です。

 - RDS
 - SQLServer
 - PerformanceInsights

## RDS

言わずと知れたAWSマネージドリレーショナルデータベース。
少し前までは、LinuxとかにOracleだのMySQLだのをインストールして、DBサーバとして利用していたと思います。
これが、LinuxとかのOS層をAWSの管理に任せて、DBだけ利用できるようにしたサービスです。
なので、アプリケーションを作ったら、エンドポイントとユーザ名、パスワードですぐにDBを利用することができます。
すぐにアプリケーション開発に取り掛かることができますし、面倒なメンテナンス等も本当に簡単にできます。
本当に便利な世の中になりました。

参考（公式ページ）：https://aws.amazon.com/jp/rds/

## SQL Server

Microsoft謹製のデータベース。
Windowsと非常に親和性が高く、アプリケーションサーバはIIS、
データベースサーバはSQLServerというのはよく見る構成かなと思います。
私はDBあまり明るくないのですが、同じ製品に揃えたほうが親和性は高いのかなと思います。

https://www.microsoft.com/ja-jp/sql-server/sql-server-2019

## Performance Insights

こちらもAWSのサービスで、性能情報を確認することができるものです。
性能情報を確認するサービスは同様のものでCloudWatchがありますが、
こちらはどっちかというとCPU使用率、メモリ使用率、NetworkIO等、OS層周りの情報で、
PerformanceInsightsは、SQLの処理時間やロック時間など、DB層の情報となります。

DBのパフォーマンスチューニングに際してはどちらかというとこのDB層の情報が手掛かりとなりますので、
こちらを確認することになることと思います。

https://aws.amazon.com/jp/rds/performance-insights/


また、以前はSQLServerはこのPerformanceInsightsは利用不可だったのですが、
2019年03月に利用が開始されたので、比較的最近ですね。
(この時代に半年前を”比較的最近”と言っていいかどうかはわかりませんが。。。)

https://aws.amazon.com/jp/about-aws/whats-new/2019/03/performance-insights-is-generally-available-for-sql-server/

# ゴール

冒頭に書いたとおり、SQLServerのPerformanceInsightsを試してみるというのが趣旨です。

1.事前準備
2.負荷かけ及び結果
3.考察

結果だけ知りたい人は2.からみるといいと思います。

## 事前準備

今回は、EC2を1台作り、そこからRDSへ接続し負荷かけを行いたいと思います。
諸事情でEC2側はLinuxを利用します。

### EC2構築

ただの踏み台なので、無償枠のEC2を利用します。
その他は特に考慮点ないので適当に作ってください。
ちなみに私はRedhatLinuxのAMIで作りました。特に希望ない人はこれで。
お金もったいない人はAmazonLinuxとかでも同じことができると思います。
(あえて縛ることはないと思いますが、RDSへの接続は1433ポートを利用しますので、
セキュリティグループ等で縛るにしてもアウトバウンド1433は開けておいてください。
この文の意味がわからない人は無視していただいて問題ないです。)

参考：https://qiita.com/arashida/items/629aaed33401b8f2265c

最近は外からの攻撃とか怖いので、鍵認証でのログインとしたり、
接続元を「マイIP」とかにしておくといいと思います。

### RDS構築

続きましてRDSの構築です。
構築といってもぽちぽちボタンを押していくだけですが。
参考サイトは以下です。

https://go-journey.club/archives/11737

接続確認のところは実施不要です。EC2からアクセスするので。
ただ接続用に、エンドポイントとユーザ名、パスワードはメモしておいてください。

また、今回は保存期間を2年でいきます。

### EC2からの接続

LinuxからSQLServerに接続するときには事前に設定が必要です。
以下を参考にして必要なツールをインストールしてください。

https://docs.microsoft.com/ja-jp/sql/linux/sql-server-linux-setup-tools?view=sql-server-ver15

sqlcmdというのがコマンドラインツールらしく、oracleでいうsqlplusみたいなものかなと思います。
bcpがLOADとか一括でデータを操作するとき用のコマンドのようです。

インストールができたら、続いて接続テストを行います。
これも以下を参考にして進めてみてください。

https://qiita.com/zaburo/items/6edf7c05c5d4f5e039eb



・SQLServerへのログインコマンド

```sql

sqlcmd.exe -S <server name> -U <username> -P <password>
```
ServerNameに先ほどメモったエンドポイント名を入力します。ユーザ名とパスワードはそのままです。
そうすると結構ぬるっとログインできると思います
(Oracleとかだとメッセージ出るかと思うんですが、でなくて驚きました。不安になりました。)

・データベース作成

```sql
create database testdb
go
```
ここからはただのSQLと同じですね。
ただし、終わりにgoコマンドを発行することで、実行されるようです。

ここまででSQLServerへのログインとデータベースの作成ができました。
続いてテストテーブルおよびデータを作ります。
以下を参考にして作ってみてください。

https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-load-from-csv-with-bcp

## 負荷かけ及び結果

### 負荷掛け方法

負荷掛けはテーブルへのinsertとselectにて行います。
今回はtestTableとしてid(INT), contents(TEXT)のカラムを持つテーブルを作ったりしました。
そのテーブルへの負荷掛けシェルは以下です。

```bash:insertTable.sh
#!/bin/bash

for i in `seq 5000`;
do

randomNumber=`expr ${RANDOM} % 10000`
randomText=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 128 | head -n 1 | sort | uniq`

QUERY="INSERT INTO testTable(id, contents) VALUES (${randomNumber},’${randomText}’);”

sqlcmd -S <ServerName> -U <Username> -P <Password> -d testdb -I -Q "${QUERY}" > /dev/null

done;
```

```bash:selectTable.sh
#!/bin/bash

for i in `seq 5000`;
do

QUERY="SELECT * FROM testTable;”

sqlcmd -S <ServerName> -U <Username> -P <Password> -d testdb -I -Q "${QUERY}" > /dev/null

done;
```

これで負荷をかける準備が整いました。
上記のシェルを複数バックグラウンド実行して負荷を掛けてみます。

```console
./selectTable.sh &
./selectTable.sh &
./selectTable.sh &
./insertTable.sh &
./insertTable.sh &
./insertTable.sh &
```

### 結果

お待たせしました、お待ちかねの結果です。
スクリーンショットをいくつか貼ります。

 - 5分間隔
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216765/03ef65c7-b02d-2103-2cc2-edbadebfe3f4.png)

 - 1時間間隔
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216765/909e32af-201f-c60a-ee21-940917cc7f85.png)

 - 5時間間隔
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216765/3becfebe-af6f-d5ed-37df-a5f6dcd92e94.png)

 - 24時間間隔
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216765/5d7aee6a-d93b-7081-d52f-8b47a2573d9f.png)

 - 全て
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216765/f21a199b-0d62-3db0-a2fa-972edfcb0542.png)

※カウンターメトリクスもありますが、記載は省略します。
こうしてみるとやっぱり1時間ぐらいでみるのが見やすいですね。
「全て」に至ってはもうよくわかりません。
ただし、月次とかにするときには全てから絞っていく必要がありそうです。

### CloudWatch

AWSの性能評価サービスでCloudwatchもあります。
これはどちらかというとOS層の評価でネットワークやCPU、メモリ等の情報を確認することができます。

 - 月次での範囲
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216765/2b7c9cb5-7166-1720-ca69-aac84ebd5638.png)

 - 範囲絞り
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216765/535c3ebb-1de4-8516-bc71-76ad93ddee85.png)

メトリクスについては以下がガイドです。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/MonitoringOverview.html


## 考察

### 使用感

ちょっと触ってみましたが、綺麗だなと思いました。（小学生並みの感想）
こういう風にSQL単位で統計が見えると、遅いものとかの調査がやりやすいなと思います。

### 気になったポイント

・1ヶ月等、範囲して表示できるか？
->できる。が、"統計情報"という意味ではあまり意味がない。

・取得情報
->SQL単位での待機イベントや、全SQLとしての処理時間等をグラフィカルに確認することができる。
その他、項目についは以下参照。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_PerfInsights_Counters.html

・Cloudwatchとの違い
先述の通り、OS層とDB層の違いみたいなイメージですね。
また、アラートも設定できるようですので通知もできるかもしれません。

・待機イベントとか。
いろいろ指標値でているのでそれぞれ理解しておきたいです。
内容としては比較的わかりやすい（他のDMBS製品と同様）ですので、
そのまま知識が生きるかもしれません。

# まとめ
会社によってはDBの統計情報からパフォーマンスの予測を立てて・・・なんてやってるところもあるかもしれませんが、
それにはPerformanceInsightsは利用しづらいと思います。
どちらかというと、性能情報はCloudwatchで推移を見て、
レスポンス障害とかにどのSQLか調査するときにPerformanceInsightsを使うと良いと思いました。
ただ、性能情報の推移なんてもはやみる必要なかもしれませんけどね。(AutoScaling)


ベストプラクティスあれば教えてください。(コメ稼ぎ)
あるいは聞きたいことあればコメントください。やれる範囲でやります。