Slide 1

Slide 1 text

ja.mackerel.io クラウドネイティブに支える従量課金集計 Mackerel「daifukucho」の設計と運用 2025.11.18 CloudNative Days Winter 2025

Slide 2

Slide 2 text

登壇者の紹介 id:ne-sachirou .。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)   Mackerelでテックリードを やってゐます id:yset0 株式会社はてなにて、Mackerelの開発に従事 2

Slide 3

Slide 3 text

3

Slide 4

Slide 4 text

ものすごく大雑把に見たMackerelの仕組み 4 メトリック投稿 保存 グラフを表示 アラートを発報 等

Slide 5

Slide 5 text

従量課金集計システム「daifukucho」 名の由来は「大福帳」 大福帳は江戸時代に日本全国に普及した商業帳簿である。大帳(だい ちょう)または本帳(ほんちょう)ともいう。「大福帳」は家の繁盛 を願った美称で、商家によって名称は異なり、「大宝恵(おぼえ) 帳」や「日加栄(ひかえ)帳」といった美称も多く用いられた。 https://ja.wikipedia.org/wiki/%E5%A4%A7%E7%A6%8F%E5%B8%B3 (プロトタイプ時点では “emmacho”(「閻魔帳」)といふ名だった) 5

Slide 6

Slide 6 text

従量課金集計システム「daifukucho」 Mackerelの課金体系 (ものすごく大雑把に言ふと) ● ホスト数×n円 ● メトリック数×m円 オーガニゼーション (テナント) ごとにホスト数やメトリック数を数へ記 録するのがdaifukucho 2024/11にリリース 6

Slide 7

Slide 7 text

daifukucho以前 (2014〜2024) 7 メトリック投稿 計数 集計結果を 移動 適宜集計を 繰り返す

Slide 8

Slide 8 text

daifukucho以前 : 課題 ● 集計の計算がすごく難しい ○ 集計のタイミングなどに起因して仕様に直感的でない妥協が複数 あり、全容を把握するのがすごく難しい ○ 実際に積年のbugが見つかりつつあった… ● メトリック投稿システムのbugの影響を受けやすい ○ 誤ってメトリックを重複して投稿すると、重複して課金される ● メトリック投稿の証跡が残ってゐない ○ 計数・データ移動・数度の集計のたびに情報を失ってゐた ■ 元データを捨ててゐた ○ 何か問題があると、集計済みの情報を失ったデータと、アクセス ログをもとに起こった事を想像するしかなかった 8

Slide 9

Slide 9 text

daifukucho以前 : 2024年初頭の状況 ● 数々の金銭上の問題が起こってゐた ○ AWSインテグレーション WAF連携のメトリック数の過剰カウントに関するご報告 ■ 【続報】クラウドインテグレーション メトリック数の過剰カウントに関するご報 告 ■ (2022/06/15追記)クラウドインテグレーション メトリック数の過剰カウント ついてのお詫びと詳細のお知らせ ○ 月途中にホストの利用が全てなくなった場合に利用料金を過剰に請求していた事象につ いてのお詫びと詳細のお知らせ ○ Google Cloudインテグレーションにおける監視の不備に関するご報告 ○ ごめんなさい ● OpenTelemetryメトリック対応の課金システムを作る必要があった 9

Slide 10

Slide 10 text

これらの課題を一度に解決する魔法がないものか ● 見通しがよくbugを作り込みづらく ● メトリック投稿システムのbugの影響を受けづらく ● 問題が起こった時に証跡から調べ直せ ● パフォーマンスも申し分なく ● コストもほどほどで ● OpenTelemetryメトリックの課金根拠の集計にも対応した そんな魔法の解決策が… 10

Slide 11

Slide 11 text

解決策 ● 課金プランを整理する ○ OpenTelemetryメトリックの課金方法(メトリック数×n円)に、 他の商品の課金方法を合はせる ■ ユーザーにも不評だった部分をわかりやすくする ■ わかりやすいプランは集計もしやすい ○ B2Bらしい様々な契約条件も、営業と協力して整理する ● 新しい課金根拠集計システムを作る ○ →daifukucho 11

Slide 12

Slide 12 text

新しい課金根拠システムへの要求 ● 月毎のメトリック数・ホスト数を正しく集計する ○ 「1メトリック」「1ホスト」の意味が月の日数によって変はる ○ メトリックは往々にして遅れて届く ● できるかぎり生の証跡を残す ○ メトリックが一点投稿されるごとに一つの証跡が残ると理想 ● 利用量がユーザーに可視化される ○ テナント毎に毎日集計する ● 集計ロジックは柔軟である ○ 重複して投稿されたメトリックをある程度は「1メトリック」と してまとめたりできる ● 移行期間は旧集計システムと併存する 12

Slide 13

Slide 13 text

完成したdaifukuchoの設計 13

Slide 14

Slide 14 text

完成したdaifukuchoの処理性能 ● 近日時点で毎日1.3TBのデータを受信してゐる ● 毎日20分弱で前日のデータを集計してゐる ● インフラコストは課題になってゐない 14

Slide 15

Slide 15 text

daifukuchoをどう設計したか 素朴な設計を考へる ● メトリック1点毎にJSONを1つ生成して保存する ● 保存したデータから毎日集計する これを充分に実現できるなら、より複雑な仕組みは考へなくてよい 15

Slide 16

Slide 16 text

素朴な設計 16

Slide 17

Slide 17 text

実稼働環境でプロトタイピングする ● Athenaで一気に集計する手法で、そもそもMackerelの料金を計算で きるか? ● 極端に遅延せず保存できるか? ● 充分な速さで集計できるか? ● 高速に日々の利用量を閲覧できるか? ● 実際のインフラ代金はどれほどのものか? ● IaCできるか? ● ロジックはテスト可能か? 17

Slide 18

Slide 18 text

データを保存できるか? ● 本番の実全データをFirehoseにも送って性能を確かめる ○ 初めは社内利用のデータだけを流す ■ 段階的に、安全に ○ 本番の処理に影響を与へないやう ■ Firehoseへの送信に失敗してもエラーを起こさない(ログを 吐くだけ)やうにする ● Parquetに変換しストレージを節約する ● 商品毎にFirehoseを分ける ○ 商品ごとに流量や集計処理が全く異なるので、一緒に処理しない 18

Slide 19

Slide 19 text

データを保存できるか? バッチし忘れコスト爆発事件 ● 証跡1個ごとに新たなレコードとしてFirehoseに送ってゐた ○ Firehoseは1レコードを最低5KBに切り上げて料金を計算する ■ すごいデータ量を処理してゐる事になった ● 1000KB未満にバッファしてFirehoseに送るやうにした 19

Slide 20

Slide 20 text

Mackerelの料金を計算できるか? ● 実データを元にクエリーを書きつつ、複雑な仕様は営業と協力して調 整してゆく ● 協力が鍵 20

Slide 21

Slide 21 text

集計できるか? AWSのSAに相談して案を貰った 比較した案 ● Athena ● Glue Databrew ● Quicksight ● Redshift 21

Slide 22

Slide 22 text

集計できるか? : Athena 本命 ● データはS3に保存するのがコストも低く管理も楽 ○ S3から大量のデータを集計するならAthenaが本命 ● Glue Crawlerでテーブルを作る ○ 毎時単位でパーティショニングする ● Step Functionsで商品毎に並列処理し、エラーに対処する ● SAと議論し、「そのデータ量を処理できるかはやってみないとわか らない」と やってみたところ、できたので採用 22

Slide 23

Slide 23 text

集計できるか? : Athena Amazon Athena のパフォーマンスチューニング Tips トップ 10 | Amazon Web Services ブログ を大いに参考とした 23

Slide 24

Slide 24 text

集計できるか? : Glue Databrew ● 当時はTerraformで管理できなかった ● 悪くはなかったので試した 本命のAthenaで充分動いたのでAthenaを選んだ 24

Slide 25

Slide 25 text

集計できるか? : Quicksight ● 利用量を表示する画面を構築できそうだった ● 不特定多数のユーザーが自由に見られるページに置くと、料金がめっ ちゃ高くなる ● 画面は構築できるが、課金システムが使ふ月毎のデータを集計するに はどうせ別のシステムが必要 料金、そして二重にシステムを作って管理するのは大変なので、不採用 25

Slide 26

Slide 26 text

集計できるか? : Redshift ● 想定したデータ量を安定して処理できそうではあった ● ストレージ料金が嵩む ● 我々には運用ノウハウが無い ● AthenaでもGlue Databrewでも作れなかった時にはこれを採用する Athenaで作れたので不採用 26

Slide 27

Slide 27 text

利用量を閲覧できるか? 比較した案 ● パーティショニングし都度クエリーする ● 日毎のデータを集計しておき、それを参照する 27

Slide 28

Slide 28 text

利用量を閲覧できるか? : 都度クエリー ● 都度クエリーするコストを抑へたいので、テナント×日毎にパーティ ショニングする ○ Firehoseでパーティショニング ■ Firehoseの上限(500個/ストリーム)を超える ○ Glue Databrewでパーティショニング ■ パーティション数の上限はあり、考慮する必要がある ● そもそも都度クエリーする事による、パフォーマンスと料金への影響 が予想しづらい 事前に集計するのが、実装も難しくなく、料金も安い事がわかったの で、不採用 28

Slide 29

Slide 29 text

利用量を閲覧できるか? : 事前に集計 ● 毎日前日のデータを集計し、Auroraに保存しておく ● Auroraのパフォーマンスは予想しやすい ● Auroraの料金も予想しやすい ● 課金用に、もともとはAthenaで一月分のデータを集計するつもりで ゐたが、データが多過ぎた ○ 一日分のデータは充分に集計できる ○ 課金用にも日毎に集計しておいたデータを使ふ 以上多数の利点があり、採用 29

Slide 30

Slide 30 text

ロジックはテスト可能か? ● S3にダミーのデータを置き、クエリー結果をCIでスナップショット テストする 30

Slide 31

Slide 31 text

完成したdaifukuchoの設計 31

Slide 32

Slide 32 text

完成したdaifukuchoの設計 : 保存・集計 ● メトリックの投稿を受け付けるシステムが証跡を生成し、一定バッ ファ毎にFirehoseに送る ● Parquetに変換しS3に保存する ● 毎日Step Functionsを起動する ○ Glue CrawlerでAthenaのパーティションを作る ○ 商品毎に並列で集計する ■ Athenaで計算する ■ 結果をAuroraに書き込む 32

Slide 33

Slide 33 text

完成したdaifukuchoの設計 : 集計結果の利用 利用量画面 ● Auroraの内容を表示する 課金 ● Auroraの内容を集計し金額を計算する 33

Slide 34

Slide 34 text

利用量画面 34

Slide 35

Slide 35 text

完成したdaifukuchoの設計(再掲) 35

Slide 36

Slide 36 text

素朴な設計(再掲) 36

Slide 37

Slide 37 text

● RDSを追加することとなった ● 月末にデータが出せないと事故になるので、影響が大きい ○ 日次バッチで、毎日稼働状況を確認する ○ 稼働しなくなったとしても、障害時の対応やコンポーネントの状 態可視化もバッチの集計期間が短ければ対処しやすくなる ● 利用状況データもふつうのレスポンスで出せるようになる ● しかし、データを守る範囲が増える ○ S3だけではなく、RDSを改ざんなどから守る必要が出てきた データストアは2段構成に 37

Slide 38

Slide 38 text

● 強い権限を配らない形とするため、作業者に直接権限を渡さないよう にした ○ 具体的には、RDSのIAM認証を行うことにした ○ 参照ユーザーを整備、IAMでの許可範囲の権限のみ実行可能に ● ただし、作業でマスターパスワードは必要なことはある ○ これまでも接続ログの監査を実施しており、同一の業務手順に載 せることにした ● RDSのIAM認証の存在は把握していたが、今回初めて採用した ○ 使い心地はよかった RDSのIAM認証と接続ログの監査 38

Slide 39

Slide 39 text

● 利用状況画面を開発するにあたって、アプリケーションからRDSに接 続する必要が出てきた ○ この従量課金システムが障害時に、このアプリケーション自体へ の影響は最小限に抑える必要がある ○ “サブシステムのメンテナンス”で、本体を停止するのは、サブシ ステムではない ● さまざまなパラメータを見極めて、直接実装するのは難儀に思われた ○ いい感じにサーキットブレーカーする仕組みが今のところない ● いい感じのサーキットブレーカーを簡単に実装する必要性が出てきた 既存のシステムからのRDSの参照 39

Slide 40

Slide 40 text

● RDSには、計算の結果が入っているだけなので、RDSに高度なクエリ を実行する訳ではない ● データのユースケースからして、参照クエリは数本に収まることがわ かった ● 既存アプリケーションから直接のDB接続を行わず、HTTP APIとして 切り離したほうが、障害が起きた際の影響を最小限度に収めやすいと 判断した ○ HTTP APIを、Goで実装し、Lambdaに仕立て、API Gatewayで載 せることにした RDSを参照するプロキシを実装する 40

Slide 41

Slide 41 text

● awslabs/aws-lambda-go-api-proxy を用いて、Lambda内にHTTPア プリケーションを実装 ○ このライブラリはアーカイブされている ● OpenAPI 定義からジェネレータでコード生成 ○ コードとして書く部分は、SQLのクエリ、入出力だけ。という状 態にする ● WebアプリケーションはECSを基盤として実装することがこれまで多 かったが、想定されるリクエスト数から、Lambdaを採用することに した RDSを参照するプロキシを実装する 41

Slide 42

Slide 42 text

● Mackerelのシステムから、HTTP APIを通じて、RDSのデータを参照 することができるようになった ● 利用状況を知ることができる画面づくり ● これまでのお客様の声 ○ 毎月何台の利用になるか月末にならないとわからないから心配だ ■ 台数が変わらなければ、問題ない。とお伝えするものの、お 客様側で、台数が変わっていないことを可視化までは至らな い ○ 使いすぎては困るので見積もり、金額がどうなるか教えてほしい ■ 平均されますよ。と伝えても、響かない 利用状況を知ることができる仕組み お客様のクラウド破産を防ぎたい 42

Slide 43

Slide 43 text

● どういう機能が満たせてい る必要があるか洗い出した ● 下記のような要件が見えた ○ リアルタイムは不要 ○ 商品ごとに日毎で見える ○ グラフで見たい ○ 過去の月も遡れる ○ 昨日のデータが見れる ● 通知は必要か?という議論 もあったが、まずは見れる ところまで。を要件とした ユーザーストーリーマップとMVP 43

Slide 44

Slide 44 text

● 自分たちのサービスにない グラフの形だったので、ど ういう見せ方が良いか。を 議論 ● 積み重ね棒グラフで商品の 積み重ねと1日を表現する ○ 商品の種類が違えば、違 うグラフにする モックの手前までアイディアを出す 44

Slide 45

Slide 45 text

● 10年を超えるサービス、グ ラフのコンポーネントは大 きなデザイン変更を経験し ておらず、愛着のある人も 多い ● 積み重ね棒グラフのデザイ ンは、実装されていない ● これまでのグラフのコン ポーネントとは異なるライ ブラリを採用しつつも、カ ラースキームを踏襲 装飾にはこだわりたい 45

Slide 46

Slide 46 text

● Mackerelは、AWSなどのク ラウド監視も専門とすると ころ ● これまでAthena向けの機能 を開発していなかった ● 自分たちのシステムの様子 は自分たちのシステムで監 視しておきたい ● Athena用の機能を開発し、 リリースしました 自分たちのシステムの監視は、自分たちで 46

Slide 47

Slide 47 text

● 運用開始、1ヶ月前から本番運用さながらの体制にしていく ○ オペレーション、監視 ○ ユーザーには見えない形での利用状況画面の公開 ■ データが取得できていることを開発チーム側で把握し、ドッ グフーディング ■ 気になったところは改善を回す ● そんなある日、Athenaの調子がおかしくなった... 大福帳の仮運用を開始する 47

Slide 48

Slide 48 text

● 昨日までは動作していたが、突然実行時間が90分まで増えた ○ 普段は20分程度 ● 実行計画の結果は特に変わっていない ● Athena がクエリする先の S3バケットも、昨日のクエリ対象のバケッ トと今日の対象を見比べても、データ量に違いはあんまりない ● 複数のクエリの実行時間の増大(2倍)を確認した ● 色々手を尽くしたが、抜本的な改善はできなかった。 ○ もはやこれまでか....AWSのサポートに連絡する Athenaの調子が悪い 48

Slide 49

Slide 49 text

解消した 49

Slide 50

Slide 50 text

● お問い合わせのお返事があり、詳細をやりとりした後... ○ 本件事象の状況が改善する可能性のある修正が実施されました ● 対応してくださったことがわかった ○ 無事、元に戻った。 ● 日頃のモニタリングが功を奏する形となった ○ 従量課金に影響は出ずに、事故を防ぐことができた 障害の翌日 50

Slide 51

Slide 51 text

● Glue crawlerの実行時間が だんだん延びてしまってい た ● バケット全てをクロールす る設定になっていた ○ 増分クロールがあること を忘れていた ● 増分クロールに切り替え、 実行時間が大幅に短縮 こぼれ話 51

Slide 52

Slide 52 text

● その後、MackerelはOpenTelemetryのトレースに対応した ● 商品が増えたので、改造作業を行うことになった ● Firehoseを増設し、Athenaのクエリの設計を行う ● RDSへ保存するテーブルを追加し、画面を作る ● これまでの作業を成功パターンとして真似をすることで、高速な開発 ができた その後 52

Slide 53

Slide 53 text

今のdaifukucho 53

Slide 54

Slide 54 text

● Athenaによる集計処理がコアとなり、Mackerelの従量課金集計シス テムは作られています ● Firehose、Athena、S3、RDS、API Gateway等、マネージドサービ スを主体とした構成でメンテナンスフリーを達成しています ● プロトタイピングで実装を本番環境に組み込み、実データを持ちいた 開発工程を実現することで、実稼働さながらのクエリチューニング等 で手戻りを減らすことができました まとめ 54

Slide 55

Slide 55 text

ご清聴ありがとうございました 55