こんにちは、TVerの加我です。
こちらは TVer Advent Calendar 2023 と New Relic 使ってみた情報をシェアしよう! by New Relic Advent Calendar 2023 の8日目の記事です。
みなさまNew Relicを活用していますか?サービスの信頼性を担保していますか?オブザーバビリティの導入・実現に向けてNew Relicを使い倒していますか?
New Relicは非常に高機能なオブザーバビリティプラットフォームです。TVerではフロントエンドからバックエンドまでNew Relicを活用した横断的な観測を行っています。しかしNew Relicを導入し活用していくにつれて気になってくるのがコストです。
ということで、New Relicを活用しつつコストを最適化するためのポイントについて考えていきます。
New Relicのコスト計算についておさらい
まずはNew Relicの価格設定について理解していきましょう。
New Relicでは「有償のユーザー数」と「取り込むデータ量」の2点が請求対象となります。
ユーザー数による請求については後述する有償のユーザー追加がなければ変動がない部分なのでほぼ固定費、取り込むデータ量についてはアクセス数やイベント数により大きく変動することがあるため変動費と考えることができます。つまり取り込むデータ量を最適化することが重要です。
こちらについてはAdministrationのPlan & usageにて利用状況を確認することができます。
Plan & usageのUsage breakdownからView detailsを選択することでデータソース毎の取り込むデータ量を確認することができます。
1. 有償のユーザー数
New Relicには「Full Platform User」「Core User」「Basic User」という3つのユーザー種別があります。このうち有償のユーザーとして請求対象になるのは「Full Platform User」と「Core User」です。TVerではFull Platform UserとBasic Userを利用した権限管理を行っています。Core Userはユースケースがマッチしなかったので利用していません。
ユーザー区分 | 利用者 | 利用目的 |
---|---|---|
Full Platform User | エンジニア カスタマーサポート |
バックエンドAPIのTransaction調査 モバイルアプリのクラッシュ調査 クラウドインフラのリソース調査 |
Core User | - | - |
Basic User | ディレクター エンジニア |
ダッシュボードを通じたデータ確認 |
ユーザー毎の権限については下記ドキュメントを参照ください。
2. 取り込むデータ量
イベントやメトリクスやログといったテレメトリーデータをNew Relic (NRDB) に取り込む際に請求対象となります。TVerではフロントエンドからバックエンドまでNew Relicを利用しているため、各所で発生したテレメトリーデータがNew Relic (NRDB) に取り込まれ請求対象となります。
主なデータの発生元 | New Relicへの取り込み方法 | 主なデータソース (NRDB) |
---|---|---|
Webブラウザー | New Relic Browser | Browser events |
Mobileアプリ | New Relic Mobile | Mobile events |
バックエンドAPI | New Relic APM | APM events |
クラウドインフラ (AWSやGoogle Cloud) |
New Relic Infrastructure | Metrics Infrastructure integrations |
各種ログ | New Relic Logs | Logging |
今回はこちらの「取り込むデータ量」についてのお話です。
何が起こったのか
2022年4月のサービスリニューアル以降、定期的なNew Relic Agentのアップデートを行えていませんでした。New Relic Agentには定期的なバグフィックスやセキュリティアップデートや機能追加が行われているため、2023年3月12日頃に諸々のAgentのアップデートを行いました。しかしアップデートを実施した結果、New Relic Browser Agent (Web) の更新によりBrowser eventsで取り込むデータ量が10倍程度に膨れ上がってしまいました。
New Relicのサポートにもアップデート内容の確認や原因の調査についてご相談したのですが、残念ながらこれという決定的な証拠を見つけることができませんでした。可能性としては「当初の設定の不備により必要なデータを取得できていなかった」もしくは「分散トレーシング周りのアップデートがあり取得できるイベントが増えた」かと考えています。
当時はNew Relicを駆使してサービスの信頼性を可視化・担保するというミッションを推進していたため「今はどんどん可視化を進めていきたい」「何はともあれオブザーバビリティ」といった流れで進めていった結果、データ量やコストの意識が二の次になってしまいました。New Relicにかかるコストのオブザーバビリティは後回しになってしまい恥ずかしい限りです。
特定のURLが高頻度で閲覧されていたりスクレイピングされている可能性も疑いましたが、全体的なイベント数が増加していることを確認して改善案を考えました。
改善
取り込むデータ量の可視化と通知、そしてデータ量の削減という二軸で対応しました。
1. 取り込むデータ量の可視化 & 定期的な通知
まずは「現状どのような取り込みデータ量になっているのか」「いつからデータ量が増加したのか」「どのデータソースで増加があったのか」を判断できるようなデータおよびダッシュボードを整備しました。そのためにNew Relicアカウント別のグラフとデータソース別のグラフを用意しました。
NRQLだとこんな感じです。24時間のグラフだと増減がわかりにくかったので3日間のデータを毎日見るようにしています。
# [前日比] アカウント別のデータ量 SELECT rate(sum(GigabytesIngested), 1 day) AS avgGbIngestTimeseriesByAccount FROM NrConsumption WHERE productLine = 'DataPlatform' FACET consumingAccountName TIMESERIES AUTO SINCE 3 days AGO COMPARE WITH 1 day ago
# [前日比] データソース別のデータ量 SELECT rate(sum(GigabytesIngested), 1 day) AS avgGbIngestTimeseries FROM NrConsumption WHERE productLine = 'DataPlatform' FACET usageMetric LIMIT MAX TIMESERIES AUTO SINCE 3 days AGO COMPARE WITH 1 day ago
上記のNRQLをグラフにしたのが下記のスクリーンショットです。
また、バックエンド (New Relic APM, New Relic Infrastructure) に比べるとフロントエンド (New Relic Browser, New Relic Mobile) の方がデータ量にばらつきが大きいことがわかっているため、主要なイベント数の推移を把握できるグラフを用意しました。こちらも24時間のグラフだと増減がわかりにくかったので3日間のデータを毎日見るようにしています。
# とあるBrowserアプリケーションのグラフをイベントごとに作成 SELECT count(*) FROM AjaxRequest WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM BrowserInteraction WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM JavaScriptError WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM PageView WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM PageViewTiming WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago
# とあるMobileアプリケーションのグラフをイベントごとに作成 SELECT count(*) FROM Mobile WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM MobileCrash WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM MobileRequest WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM MobileRequestError WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM MobileSession WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM MobileVideo WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago SELECT count(*) FROM Span WHERE appName = '<モバイルアプリ>' TIMESERIES
上記のNRQLをグラフにしたのが下記のスクリーンショットです。各グラフをStacked Bar形式にして積み上げて確認しています。
推移を見るグラフが整備できたのであればあとは通知です。クラスメソッド株式会社の新井成一さんがNew RelicのダッシュボードをSlackへ定期的に投稿するためのツールを公開してくれていたため、こちらを利用させていただきました。
実際にSlackに送られるとこのような感じになります。
これにより、データ量の推移と異常を見逃すことがなくなりました。Anomalyでデータ容量に対してアラートを設定するのもアリかもしれません。
2. 取り込みデータ量の削減
New Relicで取り込みデータ量を削減するには「取り込みデータのサンプリングを実施する」か「Data Drop Ruleを設定してデータの除外設定をする」という2つの方法があります。当時はデータのサンプリングについての検証が行えていなかったため、素直にData Drop Ruleを設定して不要なデータを除外する方向で対応しました。
Data Drop RuleについてはNerdGraphというGraphQLのAPIを利用してデータを除外するためのルールを作成・削除することが可能です。
NerdGraph API Explorer にアクセスすると下記のような画面が表示されます。
例えばDrop Ruleの一覧を取得したい場合には下記のようなクエリを入力して実行することでDrop Ruleの一覧を取得することが可能です。
{ actor { account(id: <対象となるNew RelicのアカウントID>) { nrqlDropRules { list { rules { id nrql accountId action createdBy createdAt description } error { reason description } } } } } }
また、Drop Ruleを追加したい場合には下記のようなクエリを入力して実行することでDrop Ruleを追加することが可能です。
DROP_DATAは指定したNRQLに該当するデータを除外するもの、DROP_ATTRIBUTESはNRQLに該当する属性・カラムのデータのみを除外することが可能です。
mutation { nrqlDropRulesCreate( accountId: <対象となるNew RelicのアカウントID> rules: {action: <DROP_DATA|DROP_ATTRIBUTES>, description: "<Dropルールの説明>", nrql: "<Dropしたいデータを抽出するためのNRQL>"} ) { failures { error { description reason } } successes { account { id name } accountId action createdAt createdBy description creator { id name } id source nrql } } }
しかしNerdGraphはあまり利便性が高いとは言えないため、ここに関してはTerraformで管理することをおすすめします。
# drop_dataの例 resource "newrelic_nrql_drop_rule" "foo" { account_id = 12345 description = "Drops all data for MyCustomEvent that comes from the LoadGeneratingApp in the dev environment, because there is too much and we don’t look at it." action = "drop_data" nrql = "SELECT * FROM MyCustomEvent WHERE appName='LoadGeneratingApp' AND environment='development'" } # drop_attributeの例 resource "newrelic_nrql_drop_rule" "bar" { account_id = 12345 description = "Removes the user name and email fields from MyCustomEvent" action = "drop_attributes" nrql = "SELECT userEmail, userName FROM MyCustomEvent" }
Resource: newrelic_nrql_drop_rule registry.terraform.io
Data Drop Ruleの整備により不要なデータを除外することに成功しました。オレンジ色のBrowser eventsの領域が小さくなっていることがわかります。この後に青のMobile eventsを最適化するためにDrop Ruleの調整を行っています。
今後の展望
現在モバイルアプリ開発にて取り込みデータのサンプリングの検証を進めており、Data Drop Ruleとサンプリングの併用でデータ量の最適化を行う予定です。
私達が不要と考えて除外している特定のデータが実はユーザーの体験に関わる問題に関連しており、それを見逃してしまうという可能性を回避したいというのが背景です。本来であれば全てのデータを取得したうえで一律に削減したほうが良いと考えていますが、まだまだ検証中の段階でありリリースは2024年前半の見込みです。
まとめ
TVerにおけるオブザーバビリティの導入・推進の裏側で発生していたデータ量とコストの問題にフォーカスした記事でした。パブリッククラウドもSaaSも便利ですが請求に影響するデータのチェックを怠ってはいけません。1つの設定変更で大きな請求が発生してしまう可能性があります。まずはしっかりと状況を可視化したうえで対処していきましょう。
余談ですが、株式会社ヘンリー様のエンジニアブログにある「オブザーバビリティにはお金がかかる」という記事を拝見しまして「私も会社にはNew Relicとオブザーバビリティの重要さについて説明してきたし理解して貰ってると思うけど、とはいえ安くはないし悩ましいよなぁ・・・」という思いから今回の記事の執筆のモチベーションとさせていただきました。