CloudWatchメトリクスからボトルネック要因を切り分けてみよう（EC2/RDS）

## やりたいこと
CloudWatchのメトリクスを見ることで、ボトルネックの要因がEC2かRDSかを可能な限り切り分けたい

## 背景
少し複雑なため、箇条書きで経緯を書きます
- イベント時（高負荷時）の負荷分析の必要性が生じた
- 分析を行ったところ、イベント時にALBの504エラーやUnhealthyホストのメトリクスが高くなっていた（「ボトルネック」はこのことを指していた）
- 事前の負荷分析で、EC2（MW）の設定が主な原因だったという仮説が出ていた
- ただ、追加の質問として以下の質問が来ていた
    - イベント時にRDSへの接続数も著しく増加していた
    - RDSへの接続数増加が上記のボトルネックの要因となっていたということはないか
    - ボトルネック要因の切り分けをする際はどのメトリクスを見れば良いか
- 調査にあたって、調査者が可能なのはAWSのマネコンにReadOnly権限で入り、その権限で見られる範囲のみを調査すること、という制限がある

という背景をもとに今回の調査を行います

そのため、今回の記事は
- ボトルネックの要因がどこにあるか結論を出すものではない
- あくまで、調査できる範囲に制限がある中で「ここを見ると良いかも」程度の提案を行う記事である
という前提で読んでください

また、諸事情によりメトリクスのスクショ等は少なめになります

## 調査方針
- データの流れがALB→EC2→RDSとなっているため、RDSのパフォーマンスが悪化すればEC2、ひいてはALBのパフォーマンス悪化（ボトルネック）につながる、と仮定する
- 接続数の急増によってRDSのパフォーマンスが悪化したかどうかを各種メトリクスを見て確認する
- EC2のメトリクスに問題があることは事前に調査済みのため、RDSのメトリクスに問題がなければRDSがボトルネックの大きな要因とは言えない、とある程度の結論を出せる
- イベントは1/31で、調査開始日が2/13のため、Performance Insights(以下PI)で当時のメトリクスを見ることは不可能
- そのため、主にCloudWatch(以下CLW)でメトリクスを確認する

ということで、今回の主眼は「接続数が急増すると悪化しそうなCLWのメトリクスを確認する」ということになります

## メトリクスの確認
### 1.CLWの推奨メトリクスを確認する
まずは公式ドキュメントでCLWの監視項目として推奨されているRDSのメトリクスを確認します（[推奨アラーム/Amazon RDS](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#RDS:~:text=%E6%BC%94%E7%AE%97%E5%AD%90%3A%20GREATER_THAN_THRESHOLD-,Amazon%20RDS,-CPUUtilization)）

- CPUUtilization
- DatabaseConnections
- EBSByteBalance%
などのメトリクスが挙げられていますが、全てを1から確認するのは非効率的ですし、資料にする際にもデータが多すぎてしまいます
なので、あくまで「RDSへの接続数が急増したときに悪化しそうなメトリクスはどれか」という視点で見るべきメトリクスを選んでいきましょう

## 2.メトリクスの選定をする
とはいえ、自分が調べた限り「RDSへの接続数が増えるとこのメトリクスが悪化する」、もしくは「RDSのこのメトリクスが悪化するとEC2のこのメトリクスに影響を与える」という結論を出している資料は見当たりませんでした（知ってる方がいたら教えていただきたいです）
そこで、あくまで参考にはなりますが、いくつかのドキュメントとAWSの機能を用いて、以下のメトリクスを選定しました
これらのメトリクスは全てCLWから確認でき、高負荷時から時間が経ってしまっている（PIでデータが見えない）場合でも当時のデータを見ることができるメトリクスになります

- [CPUUtilization](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#RDS:~:text=Amazon%20RDS-,CPUUtilization,-%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%3A%20DBInstanceIdentifier)
- [DatabaseConnections](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#RDS:~:text=%E6%BC%94%E7%AE%97%E5%AD%90%3A%20GREATER_THAN_THRESHOLD-,DatabaseConnections,-%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%3A%20DBInstanceIdentifier)
- [FreeStorageSpace](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#RDS:~:text=%E6%BC%94%E7%AE%97%E5%AD%90%3A%20LESS_THAN_THRESHOLD-,FreeStorageSpace,-%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%3A%20DBInstanceIdentifier)
- [FreeableMemory](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#RDS:~:text=%E6%BC%94%E7%AE%97%E5%AD%90%3A%20LESS_THAN_THRESHOLD-,FreeableMemory,-%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%3A%20DBInstanceIdentifier)
- [ReadLatency](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#RDS:~:text=%E6%BC%94%E7%AE%97%E5%AD%90%3A%20GREATER_THAN_THRESHOLD-,ReadLatency,-%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%3A%20DBInstanceIdentifier)
- [WriteLatency](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Best_Practice_Recommended_Alarms_AWS_Services.html#RDS:~:text=%E6%BC%94%E7%AE%97%E5%AD%90%3A%20GREATER_THAN_THRESHOLD-,WriteLatency,-%E3%83%87%E3%82%A3%E3%83%A1%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%B3%3A%20DBInstanceIdentifier)
- ReadIOPS と WriteIOPS
- ReadThroughput と WriteThroughput
- DiskQueueDepth
- BurstBalance (gp2 ストレージ用)

## メトリクス選定の参考にした資料

### CloudWatchの「アラームに関する推奨事項」
こちらの機能は、AWSからアラームの設定を推奨されているメトリクスを分かりやすく表示する機能です
> CloudWatch は、すぐに使えるアラームの推奨事項を提供します。これらは CloudWatch アラームで、他の AWS のサービスによって公開されるメトリクス用に作成することをお勧めするものです。これらの推奨事項は、モニタリングのベストプラクティスに従うためにアラームを設定すべきメトリクスを特定するのに役立ちます。推奨事項では、設定すべきアラームのしきい値も提案されています。これらの推奨事項に従うことで、AWS インフラストラクチャの重要なモニタリングを見逃さないようにできます。
[AWS のサービスに関するベストプラクティスアラームの推奨事項](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Best-Practice-Alarms.html)

このフィルターを有効化すると、今回の環境の場合は
- CPUUtilization
- DatabaseConnections
- FreeStorageSpace
- FreeableMemory
- ReadLatency
- WriteLatency

の項目がピックアップされていました
CPU使用率やレイテンシーなどRDSのパフォーマンスを測る基本的なメトリクスが挙げられているため、まずはここを確認します

### RDSのトラブルシューティングに関するドキュメント
- [Amazon RDS DB インスタンスの書き込みレイテンシスパイクのトラブルシューティングを行うにはどうすればよいですか?](https://repost.aws/ja/knowledge-center/rds-write-latency-spikes)
- [Amazon RDS インスタンスの IOPS のボトルネックによって引き起こされた Amazon EBS ボリュームのレイテンシーをトラブルシューティングするにはどうすればよいですか?](https://repost.aws/ja/knowledge-center/rds-latency-ebs-iops-bottleneck)

上記ドキュメント内で確認するべきメトリクスとして挙げられているのは、「アラームに関する推奨事項」で挙げられている項目に加え、

- ReadIOPS と WriteIOPS
- ReadThroughput と WriteThroughput
- DiskQueueDepth
- BurstBalance (gp2 ストレージ用)

の項目です
主にRDSの処理が問題なく行えているかを確認する項目なので、RDSへの接続数が増えたことで処理パフォーマンスが下がっていなかったか確認できます
また、こちらのドキュメント内には上記項目の参考閾値も書いてあるため、自分でメトリクスを見る際の参考にすることができます

## 実際にメトリクスを確認してみる
では、今回の場合は上記のメトリクスはどうだったのでしょうか
いくつか実際のメトリクスを見ていきます

- CPU使用率(CPUUtilization)
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933678/28b28107-d4e7-4e16-a245-aa306fa28e37.png)

- 読み取りレイテンシー(ReadLatency)
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933678/35fbce8b-222d-4e9c-9116-191aae283803.png)

- 未処理のディスクI/Oアクセス数(DiskQueueDepth)
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933678/f8f5330d-7d2e-410b-bbb8-21b1af2ec4ab.png)

これらを見ると、接続数の増加時に多少メトリクスが跳ねている部分はあるものの、パフォーマンスに影響を及ぼすほどではありません
他のメトリクスを確認しても、特に問題はありませんでした

これらから、RDSへの接続数がRDSのパフォーマンスに影響した可能性は低く、ひいてはRDSがボトルネック要因になった可能性は低いと、ある程度の判断が可能になりました

## まとめ
今回は限られた権限・情報でボトルネック要因の切り分けを行う際に見るとよいメトリクスを挙げてみました
もちろん、可能であれば見られる限りのメトリクスを見た方が良いですし、PIでデータが見られる期間であればPIのメトリクスも確認するべき、ということは大前提ですが、お客様環境など好き勝手にデータが見られない状況の時に、より効率的に状況整理をする際の参考になれば幸いです

また、閾値や許容される負荷などはAWS公式から推奨値が提示されている場合がありますが、あくまで実際のシステムの使用方法やお客様の要望などに照らし合わせてメトリクスを見るようにしましょう

以上です
見ていただきありがとうございました