New RelicでElastiCache for Redisが帯域上限まで使用されていることに気づいた話

# はじめに
この記事はNew Relic Advent Calendar 2023 シリーズ1の13日目です。

New Relicの分散トレーシングを確認してElastiCache for Redisが帯域限界まで使用されていることに気づいた話をします。


# New Relicでの確認
New Relicの分散トレーシングによってあるトランザクション内で行われる処理の内訳がタイムラインで分析できます。

これはあるトランザクションのスパンです。
![スクリーンショット 2023-12-12 16.50.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/4667de1b-5ceb-c121-fd78-171020571c53.png)


弊社の朝日新聞デジタルの記事ページ（例： https://www.asahi.com/articles/ASRDF3R1GRDFUTFK003.html ） についてのトランザクションです。

New Relicでトランザクションを眺めていると、こうしたスパンがいくつか再現していることに気がつきました。

# 課題
問題はRedisのレスポンス速度が遅すぎることです。
いくら並行処理になってるとはいえ、Redisからのレスポンスが6ミリ秒、5ミリ秒というのは想定外に感じます。
Redisのスロークエリログのデフォルト値がマイクロ秒のオーダーを期待します。

Redisが公式でオプティマイズを案内している資料からも、良い状態とはいえなさそうです。
https://redis.io/docs/management/optimization/latency/

## 調査
まず、CPUとメモリの使用率を確認しました。
AWSのメトリクスはまだNew Relicに未連携だったのでどちらもCloudwatch Metricsで確認しました。

![スクリーンショット 2023-12-12 19.01.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/50bfa0fd-ef7a-f16b-a119-ee1991cd42f5.png)
![スクリーンショット 2023-12-12 19.01.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/e654ffbc-d955-2e12-bd4b-b0c43230f1bf.png)

使用しているインスタンスは`cache.m4.large`ですが、CPU使用率、残メモリともに異常はなさそうです。

コンピューティングリソースに異常はなさそうだったのでネットワーク関連を調査しました。
![NewtworkByOut.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/1b5b61b6-8610-6a5b-759a-da59883e685e.png)
 ネットワークのI/Oを確認すると、プライマリインスタンスから外部への通信量が最大で3.4GB/分あることがわかりました。

 ※今回調査したElastiCache for　Redisはクラスターモードを有効にしていますが、2台しかノードがなく、READONLYコマンドを発行していないので全てプライマリインスタンスにリクエストがリダイレクトしています。


## 原因
ワークロードの通信量が`cache.m4.large`のベース帯域の上限に達していました。

3.4GB/分はGbpsに変換すると0.453...Gbpsとなり、ベース帯域の上限に合致します。
そのため、Redisからのキャッシュ取得量が一定以上の時に帯域上限に引っかかってレイテンシが遅くなってしまっていたと推測できます。
![スクリーンショット 2023-12-11 20.44.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/4db98970-dfb6-a6bc-3260-a6c9890b9322.png)







## 解決方針
最新の`cache.m7g.large`にスケールアップしました。
2vCPU、16GBメモリで`cache.m4.large`と同じリソース量ですが、帯域上限がほぼ倍あります。
![スクリーンショット 2023-12-11 20.44.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/dfc80152-c851-3c68-3e17-f4527e4a83e4.png)

また、`cache.m4.large`は0.226USD/月ですが、`cache.m7g.large`は0.202USD/月で使用可能です。

![スクリーンショット 2023-12-11 21.07.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/204c1d04-6f62-5394-c017-48750af7bc42.png)


![スクリーンショット 2023-12-11 21.07.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/48a9b41e-2865-7649-6458-1c289268884f.png)

このスケールアップは2023/11/15の01:00~02:00（JST）で行いました。
New Relicで当初課題となったトランザクションのRedisのレスポンス速度を見てみると、スケールアップ前後で20%程度向上していることがわかります。
![スクリーンショット 2023-12-12 19.52.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/d50daca4-7576-ef64-b5e2-22af8f69a669.png)


スケールアップ前後で99%tileでの記事ページ全体のレスポンスが30ミリ秒ほど短縮できました。

- スケールアップ前
![スクリーンショット 2023-11-21 14.03.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/28401528-ae1c-fd1f-5015-ab94b500b292.png)


- スケールアップ後
![スクリーンショット 2023-11-21 14.05.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269233/3f34b43e-e4a4-b4f6-5ccc-469a33165b1c.png)

小さな改善ですが、ElastiCacheの帯域にボトルネックがあったことに気づけて良かったです。

# まとめ

New Relicの分散トレーシングでRedisのレスポンス速度が遅い点を発見し、帯域のボトルネックを解消までを行いました。
分散トレーシングで処理ごとの内訳をサービスを跨いで閲覧できることで、ボトルネックを見つけやすいと思います。
AWSリソースはインスタンスタイプごとに帯域が設定されていますが、小さいインスタンスタイプは`小`や`中`と明示されていない資料も多いです。設計時から時間が経ってRedisにキャッシュするオブジェクトが肥大化していってしまい、当初は厳密に考慮しなくても良かった帯域の制限に達してしまいました。