Yappli Tech Blog

株式会社ヤプリの開発メンバーによるブログです。最新の技術情報からチーム・働き方に関するテーマまで、日々の熱い想いを持って発信していきます。

New Relicを活用してECS/Fargateのキャパシティ見直しを実施しコスト削減した話

この記事はヤプリ Advent Calendar 2023 & New Relic Advent Calendar 2023の21日目の記事です。

こんにちは。New Relic大好きSREグループの三橋です。
本日はECS/FargateのNew Relicを活用してキャパシティの見直しを行い、コストを削減した話について記載します。

※ 本記事は主にNew Relicの活用方法にフォーカスしたものです。

概要は下記の通りです。

  • New Relic上で実稼働しているサービスのトラフィック情報を分析しボトルネックになっている処理を特定した
  • その処理を実行するエンドポイントに対しNew Relicダッシュボードでモニタリングしながら負荷試験を実施し限界性能を測定した
  • その結果ボトルネックを特定することができ、現在のキャパシティでは性能的に余裕がありそうであることが判明した
  • 最終的にECS/Fargateのキャパシティを調整することでコストを60%削減することができた

想定する読者

  • New Relicの活用事例についてご興味のある方
  • オブザーバビリティの力を堪能したい方
  • Yappliの裏側にご興味のある方

対象システムの構成

対象システムのごく簡単な構成図は下記の通りです。

  • ServiceA: コンテンツデータの配信を行うサービス
  • ServiceB: コンテンツデータの管理を行うサービス

ECS/Fargateではコスト最適化のため時間ベースでのオートスケーリングの設定はされていますが、基本的には固定のタスク数でサービスを稼働させておく必要があります。これはpush通知などによるスパイクアクセスに耐えられるようにするためです。

このような構成になっている理由やYappliの仕組みについては下記ブログにまとめられているため、ここでは割愛します。

tech.yappli.io tech.yappli.io

今回はこの構成図のServiceB(コンテンツデータ管理サービス)のキャパシティの見直しを実施しました。

背景

今回の取り組みに至った背景は下記の通りです。

  • 本サービスのリリース時はスケジュールの都合で十分な性能試験を行うことができなかった(明確なボトルネック特定までは至れなかった)
  • 性能試験を行ったのが2年以上前で当時と状況が変わっている可能性があった
  • New Relicの導入が進みボトルネックの特定作業が以前に比べ格段に楽になった
  • システムの負荷が高まるとServiceBのエラーレートが上昇することは確認されていたが、その際にボトルネックがわからないので一旦ServiceBのタスク数を増やして様子を見るということが増えていた

目的

今回は下記を目的としています。

  • ServiceB内でのボトルネックを見つける
  • ServiceBのキャパシティが過剰ではないか確認する

一方で下記は今回の目的にはしていません。

  • システム全体でのボトルネックを見つける
  • ボトルネックの根本的な解決を行う

New Relicを活用して負荷をかけるエンドポイントを選定する

下記の理由から今回は単体のエンドポイントのみにアクセスする単純なシナリオを採用しました。

  • ServiceBを通るServiceAの処理はYappliが提供する特定の機能(入力フォーム画面を提供する機能やポイントカードを表示する機能など)を利用する場合にのみ呼び出されるようになっており、それらの機能はそれぞれエンドポイントレベルで分離されているため
  • ServiceBのエンドポイントはServiceAの様々なエンドポイントからアクセスされる可能性があるが、ボトルネックとなっている処理に対して負荷試験ができれば性能的に安全なキャパシティ(限界性能)を見積もることができると考えたため

ServiceB単体の対象エンドポイントを選定する

対象のエンドポイントは下記の処理を実行するエンドポイントに絞り込みました。

  • 時間を費やしている処理
  • 負荷増によるエラーを出していそうな処理

時間を費やしている処理は効果的に負荷をかけることができると考えたため選定対象としています。これはAPMのTransactionでSort byをMost time consumingにすることで簡単に特定することができます。

負荷増によるエラーを出していそうな処理(例えばcontext canceledなどのエラーを出している処理など)については高負荷により発生するエラーなのか確認する意味を込めて選定対象としています。これもAPMのErros Inboxから辿ることで特定することができます。

ボトルネックとなっている処理を呼び出すServiceAのエンドポイントを特定する

ServiceAはServiceBの様々なエンドポイントを叩く可能性があるため、ServiceAからも負荷をかけます。
対象はServiceBの中でボトルネックとなっている処理を呼び出す処理にのみ絞ります。

特定の処理を呼び出す上流の処理を一覧表示する機能はNew Relicには現状なさそうなのでJoin句を活用して下記のようなNRQLを書きます。
TraceIDはリクエストごとに一貫しているので、ServiceBでボトルネックとなっている処理のTraceIDを調べ、そのTraceIDが付与されているServiceAの処理を特定するという発想です。

FROM Transaction
  JOIN (FROM Transaction SELECT count(*) WHERE name = 'ServiceBのTransaction名' FACET traceId, name AS `serviceB name` LIMIT MAX) ON traceId
SELECT uniques(name) WHERE appName = 'ServiceAのAPM Service名' SINCE 1 day ago limit MAX

エンドポイントを叩く際のリクエストパラメータを決定する

Yappliでは同じ機能を利用する場合でも載せるコンテンツによって負荷のかかり方が異なってくるため、負荷試験の際には適切なリクエストパラメータを設定してあげる必要があります。
今回はAPMの情報をもとにエラーが発生しているTransactionや処理が遅くなっているTransactionを特定し、そのリクエストで使われているパラメータを使用することにしました。こちらも先ほどと同様に限界性能を見積もることができるようにするためです。

リクエストパラメータの調査はログを追ったりする必要があるため、通常では労力のかかる作業ですがYappliではある程度の計装ができているため、分散トレーシングのデータを駆使して簡単に調査することができます。

具体的な計装状況は下記の通りです。

  • Spanレベルでは個別に計装できていない
  • 最低限のContext Propagationはできている
  • New Relicが提供するライブラリを一部使用しているため自動的に計装されている部分もある
  • カスタムアトリビュートにリクエストパラメータ情報(テナントIDやアプリケーションIDなど)を一部載せている

New RelicではAPMのTransaction画面から遅い処理やエラーの起きている処理をクリックすることで分散トレーシングの画面に遷移することができます。

分散トレーシングの画面では例えば以下のような情報がリクエスト単位で確認できます

  • カスタムアトリビュート(今回の場合テナントIDやアプリケーションIDなど)
  • 接続先のDB (今回の場合sqliteファイル)
  • どこの経路を辿っているか → これは負荷試験環境を構築する際の参考になる
  • リクエストに紐づく各種サーバのログ(Logs In Contextの設定をしている場合)

New Relicを活用して負荷試験時の状況をモニタリングする

負荷試験の際にはNew Relicのダッシュボードを作成しモニタリングを行いました。
定番のDeployment Maker(チャート図の縦線)には負荷試験の際のパラメータ情報を載せています。このようにすることで後から振り返るときにどのようなパラメータで実行した際のデータかすぐにわかります。
またエラーが発生した際のTraceIDも載せておくことでどこでエラーが発生したか追えるようにしています。
画像には載っていませんがタブを分けて他のリソースについても同様のダッシュボードを作成しています。

このようにして想定外のエラー(負荷試験環境の他のリソースでのエラー)が発生した際には随時対応を行いながら負荷試験を実施しました。

まとめ

  • New Relicを活用して負荷試験対象の調査や負荷試験実施時のモニタリング、トラブルシューティングを実施し、対象サービスのボトルネックを特定することができました。また負荷試験の性能的にも余裕がありそうということが判明したためキャパシティの見直しを行いコストを60%削減することができました。
  • 今回は単純にコンポーネント単体での限界性能を見ましたが、機会があればもう少し実際のNew Relicを活用してトラフィックデータを分析し、本番と似たようなシナリオを作成してシステム全体でのボトルネック調査とその改善を行ってみたいと感じました。
  • 自分はプロダクションコードに触れることはあまりないですが、New Relicを活用することでYappliに対する深い洞察や知見を獲得することができ、オブザーバビリティの力を十分に堪能することができました。

最後に神本オブザーバビリティ・エンジニアリングのリンクを貼っておきます。

www.oreilly.co.jp