Datadog APMで始めるAPIのパフォーマンスチューニング入門

## 記載の背景 
* Datadog APMを導入しているが現状活用しきれていない
* 活用方法はいろいろあるが, APIの選び方と優先度の付け方にフォーカス
* あたりと優先度の付け方を自分なりに整理
* 今後に活かしたい

## Datadog APMについて
概要は下記をご覧ください.
https://docs.datadoghq.com/ja/tracing/

料金は下記です.
https://docs.datadoghq.com/ja/account_management/billing/apm_tracing_profiler/

導入方法は割愛します.
下記をご覧ください.
https://docs.datadoghq.com/ja/tracing/trace_collection/

## あたりと優先度をつける

### Resourcesを確認する
APM → Servicesから対象のサービスを選びます.
一番下にResourcesが存在します.

![スクリーンショット 2023-06-10 22.14.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/0aa903c3-e046-86c8-57d8-31cb761b60bf.png)

### 改善方針の確認
確認できる項目はざっくりとですが,
* リクエスト数
* 合計時間
* 待ち時間
* エラー

となっています.

![スクリーンショット 2023-06-10 22.27.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/cdec56b6-cd10-4481-102c-29f4804dfd84.png)

パッと思いつく方針は2つあります
* 待ち時間を減らしたい
* エラーを減らしたい

今回は「待ち時間を減らしたい」の方針で考えてみます.

### 待ち時間を減らしたい

#### パーセンタイルの理解
Datadogではパーセンタイルを指定できるので,
まずはパーセンタイルの理解から...

概念的には[こちら](https://www.pfa.or.jp/yogoshu/ha/ha17.html#:~:text=%E8%A8%88%E6%B8%AC%E5%80%A4%E3%81%AE%E5%88%86%E5%B8%83%EF%BC%88%E3%81%B0%E3%82%89%E3%81%A4%E3%81%8D,%E3%81%AE%E3%81%8B%E3%82%92%E6%B8%AC%E5%AE%9A%E3%81%99%E3%82%8B%E5%8D%98%E4%BD%8D%E3%80%82)を参照にしてください.

![スクリーンショット 2023-06-13 21.47.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/e03e67c1-0365-3bcd-7dbe-818e312cc1e3.png)

ResourcesのAPIにカーソルを合わせると `View` というボタンが出てくるので,
それを押すと詳細画面にいけます.
そこでパーセンタイルグラフを確認すると良いです.
Datadogでは下記のように縦軸がリクエスト数, 横軸が待ち時間となっております.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/52ed9daa-5996-ca7a-6cef-ef34ecabc098.png)

パーセンタイルから読み取りましょう.
Datadog APMにおけるP50はリクエストの半数を指します.
よって半分のリクエストは 29.22ms~1.64sの待ち時間が発生していることになります.
P50~P99を残りの半数とすると,
半分のリクエストは 1.64s~22.22sの待ち時間が発生していることになります.
P99~は数リクエストでMaxが47.82sなので外れ値になりそうです.
0s ~ 478ms(カーソル当てると秒数出てきます)の待ち時間のリクエストが一番多いです.

では下記で実践します.

#### 実践
下記のようにP99で上位から並び替えた内の上位5つで考えてみます.
P50, P90, P90を追加して, 期間は1ヶ月で絞り込んであります.

今回の前提は下記にしました.
```
* リクエスト数が1kを超えているAPIを優先
* 約8割のリクエストの待ち時間で比較したいので75パーセンタイルでの待ち時間を比較する
* 待ち時間が一緒だった場合は総リクエスト数で比較
```

基本的な考えは下記になるはず(違かったらスミマセン)
```
* 一覧にて一番高いパーセンタイルで並び替え
  * 目的次第で一番高いパーセンタイルを決めると良いはず
  * P99より上(P100)を考慮対象外とするならP99で
  * P90より上(P90~P100)を考慮対象外とするならP90で
* ほとんど利用されていないAPI(利用されていないの定義は各々で...)は優先度が低くなる
* 残ったAPIのパーセンタイルグラフを確認する
* 比較して優先度判断する
* それでも決まらなければ総リクエスト数で判断する
```

![スクリーンショット 2023-06-11 21.47.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/eab9c394-4573-9ae0-c8d0-d5f7be168efa.png)


まずはリクエスト数を確認して, 
1kリクエストされていない上から2番目と3番目のAPIは優先度を落とします.
その中でリクエスト数で比較すると上から3番目が優先度が一番低く, 上から2番目がそれより一つ上の優先度になります.

![スクリーンショット 2023-06-11 21.47.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/7295af00-97bb-151b-1b6d-5363ab87ac86.png)

他のAPI3つのパーセンタイルグラフを確認していきます.
一覧で判断でもOKです.

上から1番目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/92857040-abef-fff8-62bb-79ef43c063dc.png)

上から4番目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/4a036f61-a7a6-b93c-cceb-ce83b056402a.png)

上から5番目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/f14e94ac-8ba1-a88b-65a7-5a0b3d2fa096.png)

これらの情報からまず,
P75のパーセンタイルを比較して全てにおいて待ち時間が一番少ない4番目が優先度が低いことがわかります.

![スクリーンショット 2023-06-11 21.47.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/849ddb5a-7550-e3b4-339b-3453fdc92fa1.png)

残りの二つを比較すると下記のようになります.
1番目 : P75 = 4.86s
5番目 : P75 = 3.01s
秒数的に上から1番目が最優先, その次が上から5番目となります.

![スクリーンショット 2023-06-11 21.47.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180668/4f9ba9a1-f8f9-1d1d-196d-c42c6ca23f73.png)

こんな感じで決めていけば良いのではないかと思います.

※おまけの考え
5番目のグラフを見ると 0s~1sの待ち時間で返っているリクエストがないことがわかります.
リクエスト総数で見ると1番目のAPIの約10倍になっています.
この情報から, 
「利用頻度も高いし, 全リクエストが1s以上って絶対遅いから5番目の方が1番より優先度高くない...?」
とも判断したりもできると思いますので,
P75だけでの比較だけだと考慮が足りていない部分もあると感じています.

## 最後に
すごく理解が深まりました.
パフォーマンスチューニングを本格的に行うフェーズになったらこの知識を活かして効率よく選んでいけるといいなと思いました.
そして, 他にDatadog APMでパフォーマンスチューニングを始めようとしている方に幸あれ....!